时间:2017年08月12日星期六
说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com
教学源码:http://img.mukewang.com/down/...
学习源码:https://github.com/zccodere/s...

第一章:概述

1-1 课程简介

本课程是在之前的《初识Java微信公众号开发》课程基础之上的。
之前入门课程主要讲解了

微信公众号及公众号平台的相关概念
编辑模式和开发模式的相关操作

课程内容

消息回复接口
素材管理接口
自定义菜单接口
百度翻译API

1-2 微信公众平台测试号

因个人订阅号权限有限,很多高级接口无法使用,所以可以申请测试账号,测试账号对这些接口的权限都放开了。

第二章:素材管理接口

2-1 图文消息

复制项目wxdevaccess重命名为wxdevadvanced。其中POM文件如下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.myimooc</groupId><artifactId>wxdevadvanced</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>wxdevadvanced</name><url>http://maven.apache.org</url><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.1.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.36</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>
</project>

由于从此节开始,均属于代码编写,类及代码较多。这里就不全部一一展示了,请到我的github地址查看。完成后的项目结构如下

说明:由于条件限制,此项目代码均没有进行测试,这里只是显示大概开发过程。

接口文档

路径:消息管理》发送消息-被动回复用户消息》回复图文消息
地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183

2-2 获取access_token(上)

接口文档地址:https://mp.weixin.qq.com/wiki...

编写AccessToken类

package com.myimooc.wxdevadvanced.domain;import java.io.Serializable;/*** 获取 access_token 微信接口响应对象* @author ZhangCheng on 2017-08-12**/
public class AccessToken implements Serializable{private static final long serialVersionUID = 1L;private String token;private int expiresIn;@Overridepublic String toString() {return "AccessToken [token=" + token + ", expiresIn=" + expiresIn + "]";}public String getToken() {return token;}public void setToken(String token) {this.token = token;}public int getExpiresIn() {return expiresIn;}public void setExpiresIn(int expiresIn) {this.expiresIn = expiresIn;}}

2-3 获取access_token(下)

编写TokenUtils类

package com.myimooc.wxdevadvanced.util;import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;import com.alibaba.fastjson.JSONObject;
import com.myimooc.wxdevadvanced.domain.AccessToken;/*** 微信工具类* @author ZhangCheng on 2017-08-12**/
public class TokenUtils {private static final String APPID="dsadqawer2124a5wdqw1";private static final String APPSECRET = "dsadaq875w5edqwd58qwdqwbgthr4t5qa";private static final String CHARSET_FORMAT = "UTF-8";private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";/*** 发起GET请求*/public static JSONObject doGetStr(String url) throws Exception{HttpClientBuilder  builder = HttpClientBuilder.create();HttpGet httpGet = new HttpGet(url);JSONObject object = null;HttpResponse response = builder.build().execute(httpGet);HttpEntity entity = response.getEntity();if(null != entity){String result = EntityUtils.toString(entity,CHARSET_FORMAT);object = JSONObject.parseObject(result);}return object;}/*** 发起POST请求*/public static JSONObject doPostStr(String url,String outStr)throws Exception{HttpClientBuilder  builder = HttpClientBuilder.create();JSONObject object = null;HttpPost httpPost = new HttpPost(url);httpPost.setEntity(new StringEntity(outStr,CHARSET_FORMAT));HttpResponse response = builder.build().execute(httpPost);HttpEntity entity = response.getEntity();String result = EntityUtils.toString(entity,CHARSET_FORMAT);object = JSONObject.parseObject(result);return object;}/*** 获取access_token*/public static AccessToken getAccessToken(){AccessToken token = new AccessToken();String url = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);JSONObject json = null;try{json = doGetStr(url);}catch (Exception e) {}if(null != json && json.containsKey("access_token")){token.setToken(json.getString("access_token"));token.setExpiresIn(json.getIntValue("expires_in"));}return token;}
}

2-4 图片消息回复

接口文档

路径:消息管理》发送消息-被动回复用户消息》回复图片消息
地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183

2-5 音乐消息的回复

接口文档

路径:消息管理》发送消息-被动回复用户消息》回复音乐消息
地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543

第三章:自定义菜单接口

3-1 自定义菜单(上)

接口文档

路径:自定义菜单》自定义菜单创建接口
地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013

代码演示:

1.编写Button类

package com.myimooc.wxdevadvanced.domain.menu;/*** 菜单按钮* @author ZhangCheng on 2017-08-12**/
public class Button {private String type;private String name;private Button[] sub_button;public String getType() {return type;}public void setType(String type) {this.type = type;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Button[] getSub_button() {return sub_button;}public void setSub_button(Button[] sub_button) {this.sub_button = sub_button;}
}

2.编写Menu类

package com.myimooc.wxdevadvanced.domain.menu;/*** 菜单* @author ZhangCheng on 2017-08-12**/
public class Menu {private Button[] button;public Button[] getButton() {return button;}public void setButton(Button[] button) {this.button = button;}
}

3.编写ClickButton类

package com.myimooc.wxdevadvanced.domain.menu;/*** 点击按钮* @author ZhangCheng on 2017-08-12**/
public class ClickButton extends Button{private String key;public String getKey() {return key;}public void setKey(String key) {this.key = key;}
}

4.编写ViewButton类

package com.myimooc.wxdevadvanced.domain.menu;/*** 视图按钮* @author ZhangCheng on 2017-08-12**/
public class ViewButton extends Button{private String url;public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}
}

3-2 自定义菜单(下)

代码演示:

1.修改WinxinUtils类

package com.myimooc.wxdevadvanced.util;import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;import com.alibaba.fastjson.JSONObject;
import com.myimooc.wxdevadvanced.domain.menu.Button;
import com.myimooc.wxdevadvanced.domain.menu.ClickButton;
import com.myimooc.wxdevadvanced.domain.menu.Menu;
import com.myimooc.wxdevadvanced.domain.menu.ViewButton;
import com.myimooc.wxdevadvanced.domain.trans.Data;
import com.myimooc.wxdevadvanced.domain.trans.Parts;
import com.myimooc.wxdevadvanced.domain.trans.Symbols;
import com.myimooc.wxdevadvanced.domain.trans.TransResult;/*** 微信工具类* @author ZhangCheng on 2017-08-12**/
public class WeixinUtils {private static final String UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";private static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";private static final String QUERY_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";private static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";public static String upload(String filePath,String accessToken,String type)throws Exception{File file = new File(filePath);if(!file.exists() || !file.isFile()){throw new IOException("文件不存在");}String url = UPLOAD_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type);URL urlObj = new URL(url);// 连接HttpURLConnection con = (HttpURLConnection)urlObj.openConnection();con.setRequestMethod("POST");con.setDoInput(true);con.setDoOutput(true);con.setUseCaches(false);// 设置请求头信息con.setRequestProperty("Connection", "Keep-Alive");con.setRequestProperty("Charset", "UTF-8");// 设置边界String BOUNDARY = "-----------" + System.currentTimeMillis();con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);StringBuilder sb = new StringBuilder();sb.append("--");sb.append(BOUNDARY);sb.append("\r\n");sb.append("Content-Disposition;form-data;name=\"file\",filename=\""+ file.getName() + "\"\r\n");sb.append("Content-Type;application/octet-strean\r\n\r\n");byte[] head = sb.toString().getBytes("UTF-8");// 获得输出流OutputStream out = new DataOutputStream(con.getOutputStream());// 输出表头out.write(head);// 文件正文部分    把文件以流文件的方式 推入到url中DataInputStream in = new DataInputStream(new FileInputStream(file));int bytes = 0;byte[] bufferOut = new byte[1024];while((bytes = in.read(bufferOut))!= -1){out.write(bufferOut, 0, bytes);}in.close();// 结尾部分byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");//定义最后数据分隔线out.write(foot);out.flush();out.close();StringBuffer buffer = new StringBuffer();BufferedReader reader = null;String result = null;try {//定义BufferedReader输入流来读取URL的响应reader = new BufferedReader(new InputStreamReader(con.getInputStream()));String line = null;while ((line = reader.readLine()) != null) {buffer.append(line);}if (result == null) {result = buffer.toString();}} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}}JSONObject jsonObj = JSONObject.parseObject(result);System.out.println(jsonObj);String typeName = "media_id";if(!"image".equals(type)){typeName = type + "_media_id";}String mediaId = jsonObj.getString(typeName);return mediaId;}/*** 组装菜单*/public static Menu initMenu(){Menu menu = new Menu();ClickButton button11 = new ClickButton();button11.setName("click菜单");button11.setType("click");button11.setKey("11");ViewButton button21 = new ViewButton();button21.setName("view菜单");button21.setType("view");button21.setUrl("http://www.imooc.com");ClickButton button31 = new ClickButton();button31.setName("扫码事件");button31.setType("scancode_push");button31.setKey("31");ClickButton button32 = new ClickButton();button32.setName("地理位置");button32.setType("location_select");button32.setKey("32");Button button = new Button();button.setName("菜单");button.setSub_button(new Button[]{button31,button32});menu.setButton(new Button[]{button11,button21,button});return menu;}/*** 创建菜单*/public static int createMenu(String token,String menu) throws Exception{int result = 0;String url = CREATE_MENU_URL.replace("ACCESS_TOKEN", token);JSONObject jsonObject = TokenUtils.doPostStr(url, menu);if(jsonObject != null){result = jsonObject.getIntValue("errcode");}return result;}/*** 获取菜单*/public static JSONObject queryMenu(String token) throws Exception{String url = QUERY_MENU_URL.replace("ACCESS_TOKEN", token);JSONObject jsonObject = TokenUtils.doGetStr(url);return jsonObject;}/*** 移除菜单*/public static int deleteMenu(String token) throws Exception{String url = DELETE_MENU_URL.replace("ACCESS_TOKEN", token);JSONObject jsonObject = TokenUtils.doGetStr(url);int result = 0;if(jsonObject != null){result = jsonObject.getIntValue("errcode");}return result;}/*** 词组翻译*/public static String translate(String source) throws Exception{String url = "http://openapi.baidu.com/public/2.0/translate/dict/simple?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto";url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8"));JSONObject jsonObject = TokenUtils.doGetStr(url);String errno = jsonObject.getString("errno");Object obj = jsonObject.get("data");StringBuffer dst = new StringBuffer();if("0".equals(errno) && !"[]".equals(obj.toString())){TransResult transResult = (TransResult) JSONObject.toJavaObject(jsonObject, TransResult.class);Data data = transResult.getData();Symbols symbols = data.getSymbols()[0];String phzh = symbols.getPh_zh()==null ? "" : "中文拼音:"+symbols.getPh_zh()+"\n";String phen = symbols.getPh_en()==null ? "" : "英式英标:"+symbols.getPh_en()+"\n";String pham = symbols.getPh_am()==null ? "" : "美式英标:"+symbols.getPh_am()+"\n";dst.append(phzh+phen+pham);Parts[] parts = symbols.getParts();String pat = null;for(Parts part : parts){pat = (part.getPart()!=null && !"".equals(part.getPart())) ? "["+part.getPart()+"]" : "";String[] means = part.getMeans();dst.append(pat);for(String mean : means){dst.append(mean+";");}}}else{dst.append(translateFull(source));}return dst.toString();}/*** 句子翻译*/@SuppressWarnings({ "rawtypes", "unchecked" })public static String translateFull(String source) throws Exception{String url = "http://openapi.baidu.com/public/2.0/bmt/translate?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto";url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8"));JSONObject jsonObject = TokenUtils.doGetStr(url);StringBuffer dst = new StringBuffer();List<Map> list = (List<Map>) jsonObject.get("trans_result");for(Map map : list){dst.append(map.get("dst"));}return dst.toString();}
}

3-3 菜单的事件推送

接口文档

路径:自定义菜单》自定义菜单事件推送
地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141016

代码演示:

1.修改MessageRest类

package com.myimooc.wxdevadvanced.rest;import java.util.Date;
import java.util.Map;
import java.util.Objects;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;import com.myimooc.wxdevadvanced.domain.EventMessage;
import com.myimooc.wxdevadvanced.domain.NewsMessage;
import com.myimooc.wxdevadvanced.domain.TextMessage;
import com.myimooc.wxdevadvanced.util.MessageUtils;
import com.myimooc.wxdevadvanced.util.WeixinUtils;/*** 处理消息请求与响应* @author ZhangCheng on 2017-08-11**/
@RestController
public class MessageRest {private static final Logger logger = LoggerFactory.getLogger(MessageRest.class);/*** 接收微信服务器发送的POST请求* @throws Exception */@PostMapping("textmessage")public Object textmessage(TextMessage msg) throws Exception{logger.info("请求参数:{}",msg.toString());// 文本消息if(Objects.equals(MessageUtils.MESSAGE_TEXT, msg.getMsgType())){TextMessage textMessage = new TextMessage();// 关键字 1if(Objects.equals("1", msg.getContent())){textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.firstMenu());return textMessage;}// 关键字 2if(Objects.equals("2", msg.getContent())){NewsMessage newsMessage = MessageUtils.initNewsMessage(msg.getToUserName(), msg.getFromUserName());return newsMessage;}// 关键字 3if(Objects.equals("3", msg.getContent())){textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.threeMenu());return textMessage;}// 关键字 翻译if(msg.getContent().startsWith("翻译")){String word = msg.getContent().replaceAll("^翻译","").trim();if("".equals(word)){textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.threeMenu());return textMessage;}textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),WeixinUtils.translate(word));return textMessage;}// 关键字 ?? 调出菜单if(Objects.equals("?", msg.getContent()) || Objects.equals("?", msg.getContent())){textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText());return textMessage;}// 非关键字textMessage.setFromUserName(msg.getToUserName());textMessage.setToUserName(msg.getFromUserName());textMessage.setMsgType(MessageUtils.MESSAGE_TEXT);textMessage.setCreateTime(new Date().getTime()+"");textMessage.setContent("您发送的消息是:" + msg.getContent());return textMessage;}return null;}/*** 接收微信服务器发送的POST请求*/@PostMapping("eventmessage")public Object eventmessage(Map<String,String> param){EventMessage msg = new EventMessage();BeanUtils.copyProperties(param, msg);// 事件推送if(Objects.equals(MessageUtils.MESSAGE_EVENT, msg.getMsgType())){// 关注if(Objects.equals(MessageUtils.MESSAGE_SUBSCRIBE, msg.getEvent())){TextMessage text = new TextMessage();text = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText());return text;}// 菜单 点击类型if(Objects.equals(MessageUtils.MESSAGE_CLICK, msg.getEvent())){TextMessage text = new TextMessage();text = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText());return text;}// 菜单 视图类型if(Objects.equals(MessageUtils.MESSAGE_VIEW, msg.getEvent())){String url = param.get("EventKey");return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),url);}// 菜单 扫码事件if(Objects.equals(MessageUtils.MESSAGE_SCANCODE, msg.getEvent())){String key = param.get("EventKey");return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),key);}// 菜单 地理位置if(Objects.equals(MessageUtils.MESSAGE_LOCATION, msg.getEvent())){String Label = param.get("Label");return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),Label);}}return "no message";}}

3-4 菜单查询与删除

接口文档

路径:自定义菜单》自定义菜单查询接口
地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141014
路径:自定义菜单》自定义菜单删除接口
地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141015

代码演示:

1.修改WinxinUtils类

package com.myimooc.wxdevadvanced.util;import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;import com.alibaba.fastjson.JSONObject;
import com.myimooc.wxdevadvanced.domain.menu.Button;
import com.myimooc.wxdevadvanced.domain.menu.ClickButton;
import com.myimooc.wxdevadvanced.domain.menu.Menu;
import com.myimooc.wxdevadvanced.domain.menu.ViewButton;
import com.myimooc.wxdevadvanced.domain.trans.Data;
import com.myimooc.wxdevadvanced.domain.trans.Parts;
import com.myimooc.wxdevadvanced.domain.trans.Symbols;
import com.myimooc.wxdevadvanced.domain.trans.TransResult;/*** 微信工具类* @author ZhangCheng on 2017-08-12**/
public class WeixinUtils {private static final String UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";private static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";private static final String QUERY_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";private static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";public static String upload(String filePath,String accessToken,String type)throws Exception{File file = new File(filePath);if(!file.exists() || !file.isFile()){throw new IOException("文件不存在");}String url = UPLOAD_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type);URL urlObj = new URL(url);// 连接HttpURLConnection con = (HttpURLConnection)urlObj.openConnection();con.setRequestMethod("POST");con.setDoInput(true);con.setDoOutput(true);con.setUseCaches(false);// 设置请求头信息con.setRequestProperty("Connection", "Keep-Alive");con.setRequestProperty("Charset", "UTF-8");// 设置边界String BOUNDARY = "-----------" + System.currentTimeMillis();con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);StringBuilder sb = new StringBuilder();sb.append("--");sb.append(BOUNDARY);sb.append("\r\n");sb.append("Content-Disposition;form-data;name=\"file\",filename=\""+ file.getName() + "\"\r\n");sb.append("Content-Type;application/octet-strean\r\n\r\n");byte[] head = sb.toString().getBytes("UTF-8");// 获得输出流OutputStream out = new DataOutputStream(con.getOutputStream());// 输出表头out.write(head);// 文件正文部分    把文件以流文件的方式 推入到url中DataInputStream in = new DataInputStream(new FileInputStream(file));int bytes = 0;byte[] bufferOut = new byte[1024];while((bytes = in.read(bufferOut))!= -1){out.write(bufferOut, 0, bytes);}in.close();// 结尾部分byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");//定义最后数据分隔线out.write(foot);out.flush();out.close();StringBuffer buffer = new StringBuffer();BufferedReader reader = null;String result = null;try {//定义BufferedReader输入流来读取URL的响应reader = new BufferedReader(new InputStreamReader(con.getInputStream()));String line = null;while ((line = reader.readLine()) != null) {buffer.append(line);}if (result == null) {result = buffer.toString();}} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}}JSONObject jsonObj = JSONObject.parseObject(result);System.out.println(jsonObj);String typeName = "media_id";if(!"image".equals(type)){typeName = type + "_media_id";}String mediaId = jsonObj.getString(typeName);return mediaId;}/*** 组装菜单*/public static Menu initMenu(){Menu menu = new Menu();ClickButton button11 = new ClickButton();button11.setName("click菜单");button11.setType("click");button11.setKey("11");ViewButton button21 = new ViewButton();button21.setName("view菜单");button21.setType("view");button21.setUrl("http://www.imooc.com");ClickButton button31 = new ClickButton();button31.setName("扫码事件");button31.setType("scancode_push");button31.setKey("31");ClickButton button32 = new ClickButton();button32.setName("地理位置");button32.setType("location_select");button32.setKey("32");Button button = new Button();button.setName("菜单");button.setSub_button(new Button[]{button31,button32});menu.setButton(new Button[]{button11,button21,button});return menu;}/*** 创建菜单*/public static int createMenu(String token,String menu) throws Exception{int result = 0;String url = CREATE_MENU_URL.replace("ACCESS_TOKEN", token);JSONObject jsonObject = TokenUtils.doPostStr(url, menu);if(jsonObject != null){result = jsonObject.getIntValue("errcode");}return result;}/*** 获取菜单*/public static JSONObject queryMenu(String token) throws Exception{String url = QUERY_MENU_URL.replace("ACCESS_TOKEN", token);JSONObject jsonObject = TokenUtils.doGetStr(url);return jsonObject;}/*** 移除菜单*/public static int deleteMenu(String token) throws Exception{String url = DELETE_MENU_URL.replace("ACCESS_TOKEN", token);JSONObject jsonObject = TokenUtils.doGetStr(url);int result = 0;if(jsonObject != null){result = jsonObject.getIntValue("errcode");}return result;}/*** 词组翻译*/public static String translate(String source) throws Exception{String url = "http://openapi.baidu.com/public/2.0/translate/dict/simple?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto";url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8"));JSONObject jsonObject = TokenUtils.doGetStr(url);String errno = jsonObject.getString("errno");Object obj = jsonObject.get("data");StringBuffer dst = new StringBuffer();if("0".equals(errno) && !"[]".equals(obj.toString())){TransResult transResult = (TransResult) JSONObject.toJavaObject(jsonObject, TransResult.class);Data data = transResult.getData();Symbols symbols = data.getSymbols()[0];String phzh = symbols.getPh_zh()==null ? "" : "中文拼音:"+symbols.getPh_zh()+"\n";String phen = symbols.getPh_en()==null ? "" : "英式英标:"+symbols.getPh_en()+"\n";String pham = symbols.getPh_am()==null ? "" : "美式英标:"+symbols.getPh_am()+"\n";dst.append(phzh+phen+pham);Parts[] parts = symbols.getParts();String pat = null;for(Parts part : parts){pat = (part.getPart()!=null && !"".equals(part.getPart())) ? "["+part.getPart()+"]" : "";String[] means = part.getMeans();dst.append(pat);for(String mean : means){dst.append(mean+";");}}}else{dst.append(translateFull(source));}return dst.toString();}/*** 句子翻译*/@SuppressWarnings({ "rawtypes", "unchecked" })public static String translateFull(String source) throws Exception{String url = "http://openapi.baidu.com/public/2.0/bmt/translate?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto";url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8"));JSONObject jsonObject = TokenUtils.doGetStr(url);StringBuffer dst = new StringBuffer();List<Map> list = (List<Map>) jsonObject.get("trans_result");for(Map map : list){dst.append(map.get("dst"));}return dst.toString();}
}

第四章:百度翻译API

4-1 百度翻译

案例开发

通过百度翻译API来实现词组翻译功能。

百度开放服务平台

地址:http://developer.baidu.com/ms/oauth/
百度翻译API
地址:http://api.fanyi.baidu.com/api/trans/product/index
百度翻译API文档
地址:http://api.fanyi.baidu.com/api/trans/product/apidoc

代码演示:

1.编写Parts类

package com.myimooc.wxdevadvanced.domain.trans;/*** 百度翻译API* @author ZhangCheng on 2017-08-12**/
public class Parts {private String part;private String[] means;public String getPart() {return part;}public void setPart(String part) {this.part = part;}public String[] getMeans() {return means;}public void setMeans(String[] means) {this.means = means;}
}

2.编写Symbols类

package com.myimooc.wxdevadvanced.domain.trans;/*** 百度翻译API* @author ZhangCheng on 2017-08-12**/
public class Symbols {private String ph_am;private String ph_en;private String ph_zh;private Parts[] parts;public String getPh_am() {return ph_am;}public void setPh_am(String ph_am) {this.ph_am = ph_am;}public String getPh_en() {return ph_en;}public void setPh_en(String ph_en) {this.ph_en = ph_en;}public String getPh_zh() {return ph_zh;}public void setPh_zh(String ph_zh) {this.ph_zh = ph_zh;}public Parts[] getParts() {return parts;}public void setParts(Parts[] parts) {this.parts = parts;}
}

3.编写Data类

package com.myimooc.wxdevadvanced.domain.trans;/*** 百度翻译API* @author ZhangCheng on 2017-08-12**/
public class Data {private String word_name;private Symbols[] symbols;public String getWord_name() {return word_name;}public void setWord_name(String word_name) {this.word_name = word_name;}public Symbols[] getSymbols() {return symbols;}public void setSymbols(Symbols[] symbols) {this.symbols = symbols;}
}

4.编写TransResult类

package com.myimooc.wxdevadvanced.domain.trans;/*** 百度翻译API* @author ZhangCheng on 2017-08-12**/
public class TransResult {private String from;private String to;private Data data;private String errno;public String getFrom() {return from;}public void setFrom(String from) {this.from = from;}public String getTo() {return to;}public void setTo(String to) {this.to = to;}public Data getData() {return data;}public void setData(Data data) {this.data = data;}public String getErrno() {return errno;}public void setErrno(String errno) {this.errno = errno;}
}

5.修改WeixinUtils类

package com.myimooc.wxdevadvanced.util;import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;import com.alibaba.fastjson.JSONObject;
import com.myimooc.wxdevadvanced.domain.menu.Button;
import com.myimooc.wxdevadvanced.domain.menu.ClickButton;
import com.myimooc.wxdevadvanced.domain.menu.Menu;
import com.myimooc.wxdevadvanced.domain.menu.ViewButton;
import com.myimooc.wxdevadvanced.domain.trans.Data;
import com.myimooc.wxdevadvanced.domain.trans.Parts;
import com.myimooc.wxdevadvanced.domain.trans.Symbols;
import com.myimooc.wxdevadvanced.domain.trans.TransResult;/*** 微信工具类* @author ZhangCheng on 2017-08-12**/
public class WeixinUtils {private static final String UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";private static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";private static final String QUERY_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";private static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";public static String upload(String filePath,String accessToken,String type)throws Exception{File file = new File(filePath);if(!file.exists() || !file.isFile()){throw new IOException("文件不存在");}String url = UPLOAD_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type);URL urlObj = new URL(url);// 连接HttpURLConnection con = (HttpURLConnection)urlObj.openConnection();con.setRequestMethod("POST");con.setDoInput(true);con.setDoOutput(true);con.setUseCaches(false);// 设置请求头信息con.setRequestProperty("Connection", "Keep-Alive");con.setRequestProperty("Charset", "UTF-8");// 设置边界String BOUNDARY = "-----------" + System.currentTimeMillis();con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);StringBuilder sb = new StringBuilder();sb.append("--");sb.append(BOUNDARY);sb.append("\r\n");sb.append("Content-Disposition;form-data;name=\"file\",filename=\""+ file.getName() + "\"\r\n");sb.append("Content-Type;application/octet-strean\r\n\r\n");byte[] head = sb.toString().getBytes("UTF-8");// 获得输出流OutputStream out = new DataOutputStream(con.getOutputStream());// 输出表头out.write(head);// 文件正文部分    把文件以流文件的方式 推入到url中DataInputStream in = new DataInputStream(new FileInputStream(file));int bytes = 0;byte[] bufferOut = new byte[1024];while((bytes = in.read(bufferOut))!= -1){out.write(bufferOut, 0, bytes);}in.close();// 结尾部分byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");//定义最后数据分隔线out.write(foot);out.flush();out.close();StringBuffer buffer = new StringBuffer();BufferedReader reader = null;String result = null;try {//定义BufferedReader输入流来读取URL的响应reader = new BufferedReader(new InputStreamReader(con.getInputStream()));String line = null;while ((line = reader.readLine()) != null) {buffer.append(line);}if (result == null) {result = buffer.toString();}} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}}JSONObject jsonObj = JSONObject.parseObject(result);System.out.println(jsonObj);String typeName = "media_id";if(!"image".equals(type)){typeName = type + "_media_id";}String mediaId = jsonObj.getString(typeName);return mediaId;}/*** 组装菜单*/public static Menu initMenu(){Menu menu = new Menu();ClickButton button11 = new ClickButton();button11.setName("click菜单");button11.setType("click");button11.setKey("11");ViewButton button21 = new ViewButton();button21.setName("view菜单");button21.setType("view");button21.setUrl("http://www.imooc.com");ClickButton button31 = new ClickButton();button31.setName("扫码事件");button31.setType("scancode_push");button31.setKey("31");ClickButton button32 = new ClickButton();button32.setName("地理位置");button32.setType("location_select");button32.setKey("32");Button button = new Button();button.setName("菜单");button.setSub_button(new Button[]{button31,button32});menu.setButton(new Button[]{button11,button21,button});return menu;}/*** 创建菜单*/public static int createMenu(String token,String menu) throws Exception{int result = 0;String url = CREATE_MENU_URL.replace("ACCESS_TOKEN", token);JSONObject jsonObject = TokenUtils.doPostStr(url, menu);if(jsonObject != null){result = jsonObject.getIntValue("errcode");}return result;}/*** 获取菜单*/public static JSONObject queryMenu(String token) throws Exception{String url = QUERY_MENU_URL.replace("ACCESS_TOKEN", token);JSONObject jsonObject = TokenUtils.doGetStr(url);return jsonObject;}/*** 移除菜单*/public static int deleteMenu(String token) throws Exception{String url = DELETE_MENU_URL.replace("ACCESS_TOKEN", token);JSONObject jsonObject = TokenUtils.doGetStr(url);int result = 0;if(jsonObject != null){result = jsonObject.getIntValue("errcode");}return result;}/*** 词组翻译*/public static String translate(String source) throws Exception{String url = "http://openapi.baidu.com/public/2.0/translate/dict/simple?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto";url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8"));JSONObject jsonObject = TokenUtils.doGetStr(url);String errno = jsonObject.getString("errno");Object obj = jsonObject.get("data");StringBuffer dst = new StringBuffer();if("0".equals(errno) && !"[]".equals(obj.toString())){TransResult transResult = (TransResult) JSONObject.toJavaObject(jsonObject, TransResult.class);Data data = transResult.getData();Symbols symbols = data.getSymbols()[0];String phzh = symbols.getPh_zh()==null ? "" : "中文拼音:"+symbols.getPh_zh()+"\n";String phen = symbols.getPh_en()==null ? "" : "英式英标:"+symbols.getPh_en()+"\n";String pham = symbols.getPh_am()==null ? "" : "美式英标:"+symbols.getPh_am()+"\n";dst.append(phzh+phen+pham);Parts[] parts = symbols.getParts();String pat = null;for(Parts part : parts){pat = (part.getPart()!=null && !"".equals(part.getPart())) ? "["+part.getPart()+"]" : "";String[] means = part.getMeans();dst.append(pat);for(String mean : means){dst.append(mean+";");}}}else{dst.append(translateFull(source));}return dst.toString();}/*** 句子翻译*/@SuppressWarnings({ "rawtypes", "unchecked" })public static String translateFull(String source) throws Exception{String url = "http://openapi.baidu.com/public/2.0/bmt/translate?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto";url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8"));JSONObject jsonObject = TokenUtils.doGetStr(url);StringBuffer dst = new StringBuffer();List<Map> list = (List<Map>) jsonObject.get("trans_result");for(Map map : list){dst.append(map.get("dst"));}return dst.toString();}
}

6.修改MessageUtils类

package com.myimooc.wxdevadvanced.util;import java.util.ArrayList;
import java.util.Date;
import java.util.List;import com.myimooc.wxdevadvanced.domain.Image;
import com.myimooc.wxdevadvanced.domain.ImageMessage;
import com.myimooc.wxdevadvanced.domain.Music;
import com.myimooc.wxdevadvanced.domain.MusicMessage;
import com.myimooc.wxdevadvanced.domain.News;
import com.myimooc.wxdevadvanced.domain.NewsMessage;
import com.myimooc.wxdevadvanced.domain.TextMessage;/*** 消息类型及工具类* @author ZhangCheng on 2017-08-11**/
public class MessageUtils {public static final String MESSAGE_TEXT = "text";public static final String MESSAGE_NEWS = "news";public static final String MESSAGE_IMAGE = "image";public static final String MESSAGE_VOICE = "voice";public static final String MESSAGE_MUSIC = "music";public static final String MESSAGE_VIDEO = "video";public static final String MESSAGE_LINK = "link";public static final String MESSAGE_LOCATION = "location";public static final String MESSAGE_EVENT = "event";public static final String MESSAGE_SUBSCRIBE = "subscribe";public static final String MESSAGE_UNSUBSCRIBE = "unsubscribe";public static final String MESSAGE_CLICK = "CLICK";public static final String MESSAGE_VIEW = "VIEW";public static final String MESSAGE_SCANCODE = "scancode_push";public static TextMessage initText(String toUserName,String fromUserName,String content){TextMessage text = new TextMessage();text.setFromUserName(toUserName);text.setToUserName(fromUserName);text.setMsgType(MessageUtils.MESSAGE_TEXT);text.setCreateTime(new Date().getTime()+"");text.setContent(content);return text;}/*** 主菜单*/public static String menuText(){StringBuffer sb = new StringBuffer();sb.append("欢迎您的关注,请按照菜单提升进行操作:\n\n");sb.append("1、课程介绍\n");sb.append("2、慕课网介绍\n");sb.append("3、词组翻译\n\n");sb.append("回复?显示主菜单。");return sb.toString();}public static String firstMenu(){StringBuffer sb = new StringBuffer();sb.append("本套课程介绍微信公众号开发,主要涉及公众号介绍、编辑模式介绍、开发模式介绍等。");return sb.toString();}public static String secondMenu(){StringBuffer sb = new StringBuffer();sb.append("慕课网是垂直的互联网IT技能免费学习网站。以独家视频教程、在线编程工具、学习计划、"+ "问答社区为核心特色。在这里,你可以找到最好的互联网技术牛人,也可以通过免费的在线公"+ "开视频课程学习国内领先的互联网IT技术。"+ "慕课网课程涵盖前端开发、PHP、Html5、Android、iOS、Swift等IT前沿技术语言,"+ "包括基础课程、实用案例、高级分享三大类型,适合不同阶段的学习人群。"+ "以纯干货、短视频的形式为平台特点,为在校学生、职场白领提供了一个迅速提升技能、共同分享进步的学习平台。");return sb.toString();}public static String threeMenu(){StringBuffer sb = new StringBuffer();sb.append("词组翻译使用指南\n");sb.append("使用示例:\n");sb.append("翻译足球:\n");sb.append("翻译中国足球\n");sb.append("翻译football\n\n");sb.append("回复?显示主菜单。");return sb.toString();}/*** 图文消息的组装*/public static NewsMessage initNewsMessage(String toUserNmae,String fromUserName){List<News> newsList = new ArrayList<News>();NewsMessage newsMessage = new NewsMessage();News news = new News();news.setTitle("慕课网介绍");news.setDescription("慕课网是垂直的互联网IT技能免费学习网站。以独家视频教程、在线编程工具、学习计划、"+ "问答社区为核心特色。在这里,你可以找到最好的互联网技术牛人,也可以通过免费的在线公"+ "开视频课程学习国内领先的互联网IT技术。"+ "慕课网课程涵盖前端开发、PHP、Html5、Android、iOS、Swift等IT前沿技术语言,"+ "包括基础课程、实用案例、高级分享三大类型,适合不同阶段的学习人群。"+ "以纯干货、短视频的形式为平台特点,为在校学生、职场白领提供了一个迅速提升技能、共同分享进步的学习平台。");news.setPicUrl("http://imooc.jpg");news.setUrl("www.imooc.com");newsList.add(news);newsMessage.setToUserName(fromUserName);newsMessage.setFromUserName(toUserNmae);newsMessage.setCreateTime(new Date().getTime()+"");newsMessage.setMsgType(MESSAGE_NEWS);newsMessage.setArticles(newsList);newsMessage.setArticleCount(newsList.size());return newsMessage;}/*** 图片消息组装*/public static ImageMessage initImageMessage(String toUserName,String fromUserName){Image image = new Image();image.setMediaId("JTH8vBl0zDRlrrn2bBnMleySuHjVbMhyAo0U2x7kQyd1ciydhhsVPONbnRrKGp8m");ImageMessage imageMessage = new ImageMessage();imageMessage.setFromUserName(toUserName);imageMessage.setToUserName(fromUserName);imageMessage.setMsgType(MESSAGE_IMAGE);imageMessage.setCreateTime(new Date().getTime()+"");imageMessage.setImage(image);return imageMessage;}/*** 组装音乐消息* @param toUserName* @param fromUserName* @return*/public static MusicMessage initMusicMessage(String toUserName,String fromUserName){Music music = new Music();music.setThumbMediaId("WsHCQr1ftJQwmGUGhCP8gZ13a77XVg5Ah_uHPHVEAQuRE5FEjn-DsZJzFZqZFeFk");music.setTitle("see you again");music.setDescription("速7片尾曲");music.setMusicUrl("http://zapper.tunnel.mobi/Weixin/resource/See You Again.mp3");music.setHQMusicUrl("http://zapper.tunnel.mobi/Weixin/resource/See You Again.mp3");MusicMessage musicMessage = new MusicMessage();musicMessage.setFromUserName(toUserName);musicMessage.setToUserName(fromUserName);musicMessage.setMsgType(MESSAGE_MUSIC);musicMessage.setCreateTime(new Date().getTime()+"");musicMessage.setMusic(music);return musicMessage;}
}

7.修改MessageRest类

package com.myimooc.wxdevadvanced.rest;import java.util.Date;
import java.util.Map;
import java.util.Objects;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;import com.myimooc.wxdevadvanced.domain.EventMessage;
import com.myimooc.wxdevadvanced.domain.NewsMessage;
import com.myimooc.wxdevadvanced.domain.TextMessage;
import com.myimooc.wxdevadvanced.util.MessageUtils;
import com.myimooc.wxdevadvanced.util.WeixinUtils;/*** 处理消息请求与响应* @author ZhangCheng on 2017-08-11**/
@RestController
public class MessageRest {private static final Logger logger = LoggerFactory.getLogger(MessageRest.class);/*** 接收微信服务器发送的POST请求* @throws Exception */@PostMapping("textmessage")public Object textmessage(TextMessage msg) throws Exception{logger.info("请求参数:{}",msg.toString());// 文本消息if(Objects.equals(MessageUtils.MESSAGE_TEXT, msg.getMsgType())){TextMessage textMessage = new TextMessage();// 关键字 1if(Objects.equals("1", msg.getContent())){textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.firstMenu());return textMessage;}// 关键字 2if(Objects.equals("2", msg.getContent())){NewsMessage newsMessage = MessageUtils.initNewsMessage(msg.getToUserName(), msg.getFromUserName());return newsMessage;}// 关键字 3if(Objects.equals("3", msg.getContent())){textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.threeMenu());return textMessage;}// 关键字 翻译if(msg.getContent().startsWith("翻译")){String word = msg.getContent().replaceAll("^翻译","").trim();if("".equals(word)){textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.threeMenu());return textMessage;}textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),WeixinUtils.translate(word));return textMessage;}// 关键字 ?? 调出菜单if(Objects.equals("?", msg.getContent()) || Objects.equals("?", msg.getContent())){textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText());return textMessage;}// 非关键字textMessage.setFromUserName(msg.getToUserName());textMessage.setToUserName(msg.getFromUserName());textMessage.setMsgType(MessageUtils.MESSAGE_TEXT);textMessage.setCreateTime(new Date().getTime()+"");textMessage.setContent("您发送的消息是:" + msg.getContent());return textMessage;}return null;}/*** 接收微信服务器发送的POST请求*/@PostMapping("eventmessage")public Object eventmessage(Map<String,String> param){EventMessage msg = new EventMessage();BeanUtils.copyProperties(param, msg);// 事件推送if(Objects.equals(MessageUtils.MESSAGE_EVENT, msg.getMsgType())){// 关注if(Objects.equals(MessageUtils.MESSAGE_SUBSCRIBE, msg.getEvent())){TextMessage text = new TextMessage();text = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText());return text;}// 菜单 点击类型if(Objects.equals(MessageUtils.MESSAGE_CLICK, msg.getEvent())){TextMessage text = new TextMessage();text = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText());return text;}// 菜单 视图类型if(Objects.equals(MessageUtils.MESSAGE_VIEW, msg.getEvent())){String url = param.get("EventKey");return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),url);}// 菜单 扫码事件if(Objects.equals(MessageUtils.MESSAGE_SCANCODE, msg.getEvent())){String key = param.get("EventKey");return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),key);}// 菜单 地理位置if(Objects.equals(MessageUtils.MESSAGE_LOCATION, msg.getEvent())){String Label = param.get("Label");return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),Label);}}return "no message";}}

慕课网_《Java微信公众号开发进阶》学习总结相关推荐

  1. 慕课网_《微信授权登录》学习总结

    时间:2017年08月12日星期六 说明:本文部分内容均来自慕课网.@慕课网:http://www.imooc.com 教学源码:无 学习源码:https://github.com/zccodere/ ...

  2. 微信授权登录(微信订阅号使用测试账号)

    1.微信授权登录: 微信公众号测试登录: 准备: 1.1 花生壳! 下载地址:http://hsk.oray.com/download/ 1.2 微信公众号:https://mp.weixin.qq. ...

  3. 硅谷课堂 12_公众号消息和微信授权登录

    硅谷课堂第十二天-公众号消息和微信授权登录 文章目录 硅谷课堂第十二天-公众号消息和微信授权登录 一.公众号普通消息 1.实现目标 2.消息接入 2.1.公众号服务器配置 2.2.验证来自微信服务器消 ...

  4. uni app和php开发微信登录代码,uniapp如何实现微信授权登录

    uniapp实现微信授权登录的方法:首先获取对应的appid和appsecret:然后在uniapp项目的manifest.json中进行APP SDK配置和模块权限配置.最后实现编码. 本教程操作环 ...

  5. thinkphp 微信授权登录 以及微信实现分享

    <?php namespace app\wechat\controller; use think\Controller; use think\Request; /** * 微信授权登录类 * U ...

  6. code换取微信openid_微信授权登录开发的两种方式

    本文主要针对微信公众号(公众平台的开发) 首先理解一个概念:OAuth: OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表), ...

  7. Java版本微信授权登录(升级版)

    前面写了一遍文章<Java版本微信授权登录(测试版)>,可以当做入门的基础文章,这里继续做一点深入,主要解决的是,如何在本地开发中微信授权以后跳转到本地启动的项目中. 我们知道了微信公众平 ...

  8. android友盟微信授权登录清除,【转载】Android友盟SDK微信授权登录接入

    微信授权登录接入需要先到微信开放平台申请好应用的APPID,交纳300大洋费用得到授权登录权限后才能使用,此处不再赘述. 接入的两种方式 -- 微信SDK接入:使用微信官方SDK接入,需要分" ...

  9. uniapp开发h5微信授权登录(详细教程)

    uniapp开发h5微信授权登录 文章目录 uniapp开发h5微信授权登录 前言 一.前期准备--申请测试账号 二.正式开发--前端代码 三.打包发布 总结 前言 我也是第一次做h5授权微信登录,网 ...

  10. springboot微信授权登录

    水平有限!实现方法直接找的网上的以为大神所编写的api来实现,这里主要是记录一下自己实现的过程.具体方法请参考网址:https://github.com/liyiorg/weixin-popular, ...

最新文章

  1. R语言plyr包round_any函数将向量数据近似到任意精度实战
  2. zookeeper学习笔记2
  3. 1024,千家公司程序员幸福指数大比拼!最“幸福”的程序员是你吗?
  4. assert()用法
  5. MSN on 2/16/2009
  6. MySQL 可重复读,差点就让我背上了一个 P0 事故!
  7. 如何創建一個自己的 Composer/Packagist 包 (PHP)
  8. matlab符号函数与对其的常用操作
  9. 【MATLAB】基于支持向量机的简单图像识别实现
  10. 13个免费下载 SVG 图标网站
  11. Vue路由SPA介绍
  12. c语言中结构体定义中的“冒号”
  13. Cisco wlan controlller配置
  14. 传感器实验——火焰传感器
  15. 《一键下单:杰夫·贝佐斯与亚马逊的崛起》—— 读后总结
  16. 【技术分享】python web 安全总结
  17. leetcode每日一题信息抓取 早安语录 定时任务
  18. 魔兽地图编辑器插件YDWE的使用与基本设置8 游戏平衡常数
  19. Java | SpringBoot 常用注解详解
  20. Jenkins、Gitee搭建集成环境

热门文章

  1. Web API With AJAX: Handle Session in Web API
  2. C#关于值类型和引用类型的备忘
  3. Ubuntu 下添加OpenERP command 快捷启动方式
  4. paip.元数据驱动的转换-读取文件行到个list理念 uapi java php python总结
  5. 汉语是世界上唯一一种面向对象的高级语言
  6. Microsoft Expression Blend 2 密钥,key
  7. APUE读书笔记-09进程关系(04)
  8. WCF中的序列化[上篇]
  9. 一步一步学Silverlight 2系列(24):与浏览器交互相关辅助方法
  10. switch和枚举的小坑