首先,搭建好springBoot框架:
后面在WechatUtil里面调用微信公众平台接口,在IndexController里面写controller接口,自定义controller接口返回值:
package com.demo.wechat.domain;
public class Message {
private Integer code;
private Object msg;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public Object getMsg() {
return msg;
}
public void setMsg(Object msg) {
this.msg = msg;
}
public static Message getSuccessfulRes(Object obj) {
return new Message(Code.SUCCESS, obj);
}
/**
* @param code
* @param obj
*/
public Message(Integer code, Object obj) {
super();
this.code = code;
this.msg = obj;
}
}
微信公众平台的接口都是https请求,所以封装一个Https请求的 util:
package com.demo.wechat.util;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class MyX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
package com.demo.wechat.util;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import com.alibaba.fastjson.JSONObject;
public class HttpsUtil {
/**
* 发起https请求并获取结果 增加3秒超时时间
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据 ,json字符串
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
httpUrlConn.setConnectTimeout(3000);
httpUrlConn.setReadTimeout(3000);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
// 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.parseObject(buffer.toString());
} catch (ConnectException ce) {
System.out.println("Weixin server connection timed out.");
} catch (Exception e) {
System.out.println("https request error:{}"+e);
}
return jsonObject;
}
}
一、获取微信公众平台全局凭证access_token:
1、根据接口返回结果封装domain:
package com.demo.wechat.domain;
public class AccessToken{
private String accessToken;
private Long expiresIn;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public Long getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(Long expiresIn) {
this.expiresIn = expiresIn;
}
}
2、自定义util:
package com.demo.wechat.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.demo.wechat.domain.AccessToken;
import com.demo.wechat.domain.WechatMenu;
public class WechatUtil {
//获取access_token
private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
//获取access_token
public static AccessToken getAccessToken(String appId,String appSecert){
AccessToken accessToken = new AccessToken();
String url = ACCESS_TOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecert);
JSONObject res = HttpsUtil.httpRequest(url, "GET", null);
String errcode = (String) res.get("errcode");
try{
String token = (String) res.get("access_token");
accessToken.setAccessToken(token);
Long expiresIn = res.getLong("expires_in");
accessToken.setExpiresIn(expiresIn);
}catch (Exception e) {
accessToken = null;
}
return accessToken;
}
}
3、controller接口测试:
package com.demo.wechat.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import com.demo.wechat.domain.AccessToken;
import com.demo.wechat.domain.Button;
import com.demo.wechat.domain.WechatMenu;
import com.demo.wechat.domain.Message;
import com.demo.wechat.util.WechatUtil;
@RequestMapping("/index")
@RestController
public class IndexController {
@Value(value="${app.secret}")
private String appSecert;
@Value(value="${app.id}")
private String appId;
//获取access_token
@RequestMapping("/getAccessToken")
public String getAccessToken(){
AccessToken accessToken = WechatUtil.getAccessToken(appId, appSecert);
return JSON.toJSONString(Message.getSuccessfulRes(accessToken.getAccessToken()));
}
}
postman请求成功:
二、自定义菜单创建接口:
1、官方文档数据:
根据数据格式封装domain,[]为数组,{}为对象:
(1)先封装最外面一层,为一个"button"数组:
package com.demo.wechat.domain;
import java.util.List;
public class WechatMenu {
private List<Button> button;
public List<Button> getButton() {
return button;
}
public void setButton(List<Button> button) {
this.button = button;
}
@Override
public String toString() {
return "WechatMenu [button=" + button + "]";
}
}
(2)再封装里面一层,即数组里面的对象:
package com.demo.wechat.domain;
import java.util.List;
public class Button {
private String type;
private String name;
private String key;
private String url;
private List<Button> sub_button;
/**
*省略get、set方法
*/
}
2、封装创建菜单util,WechatUtil添加:
//自定义创建菜单
private static final String CREATE_MENU = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
//自定义菜单
public static Integer createMenu(String appId,String appSecert,WechatMenu wechatMenu){
AccessToken accessToken = getAccessToken(appId, appSecert);
String url = CREATE_MENU.replace("ACCESS_TOKEN", accessToken.getAccessToken());
JSONObject res = HttpsUtil.httpRequest(url, "POST", JSON.toJSONString(wechatMenu));
return (Integer) res.get("errcode");
}
3、controller接口:
//自定义菜单
@RequestMapping("/createMenu")
public String createMenu(){
WechatMenu wechatMenu = new WechatMenu();
List<Button> buttonList = new ArrayList<>();
Button button1 = new Button();
button1.setName("wtyy菜单1");
List<Button> subButtonList = new ArrayList<>();
Button subButton1 = new Button();
subButton1.setName("1的子菜单1");
subButton1.setType("click");
subButton1.setKey("key1");
subButton1.setUrl("http://www.baidu.com");
subButtonList.add(subButton1);
button1.setSub_button(subButtonList );
buttonList.add(button1);
Button button2 = new Button();
button2.setName("wtyy菜单2");
button2.setType("click");
button2.setKey("key2");
buttonList.add(button2);
wechatMenu.setButton(buttonList);
System.out.println("菜单"+JSON.toJSONString(wechatMenu));
Integer res = WechatUtil.createMenu(appId, appSecert, wechatMenu);
return JSON.toJSONString(Message.getSuccessfulRes(res));
}
postman调用:
请求成功后,打开微信公众号,可以看到多了几个菜单:
在这之前一直报40017 invalid button type的错误, 我是创建两个菜单,一个包含了子菜单,一个不包含,一开始子菜单和父菜单都写了type类型,后来把父菜单的type去掉只保留子菜单的type就成功了。
三、 自定义菜单查询接口:
//自定义查询菜单
private static final String MENU_QUERY = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";
//自定义菜单查询
public static String queryMenu(String appId,String appSecret){
AccessToken accessToken = getAccessToken(appId, appSecret);
String url = MENU_QUERY.replace("ACCESS_TOKEN", accessToken.getAccessToken());
JSONObject res = HttpsUtil.httpRequest(url, "GET", null);
return res.toJSONString();
}
//查询自定义菜单
@RequestMapping("/queryMenu")
public String queryMenu(){
String res = WechatUtil.queryMenu(appId, appSecert);
return JSON.toJSONString(Message.getSuccessfulRes(res));
}
post请求结果:
四、自定义菜单删除接口:
//自定义菜单删除
private static final String MENU_DELETE = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";
//自定义菜单删除
public static Integer deleteMenu(String appId,String appSecret){
AccessToken accessToken = getAccessToken(appId, appSecret);
String url = MENU_DELETE.replace("ACCESS_TOKEN", accessToken.getAccessToken());
JSONObject res = HttpsUtil.httpRequest(url, "GET", null);
return (Integer) res.get("errcode");
}
//删除自定义菜单
@RequestMapping("/deleteMenu")
public String deleteMenu(){
Integer res = WechatUtil.deleteMenu(appId, appSecert);
return JSON.toJSONString(Message.getSuccessfulRes(res));
}
调用后会删除所有的菜单,删除后调用查询自定义菜单接口,返回结果如下: