JAVA微信公众号网页开发——生成自定义微信菜单(携带参数)

时间:2021-05-19 14:36:21

官网接口地址:https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html

//创建一个微信菜单实体类

WeixinMenu.java

package com.weixin.menu;

import java.io.Serializable;
import java.util.Set; public abstract class WeixinMenu implements Serializable { // primary key
private Integer id; // fields
private String name;
private String type;
private String url;
private String key; // many to one
private WeixinMenu parent; // collections
private java.util.Set<WeixinMenu> child; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getType() {
return type;
} public void setType(String type) {
this.type = type;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public String getKey() {
return key;
} public void setKey(String key) {
this.key = key;
} public WeixinMenu getParent() {
return parent;
} public void setParent(WeixinMenu parent) {
this.parent = parent;
} public Set<WeixinMenu> getChild() {
return child;
} public void setChild(Set<WeixinMenu> child) {
this.child = child;
} public String toString() {
return super.toString();
} }

  

//控制器方法

WeixinMenuAct.java

package com.weixin.menu;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.URI;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;
import java.util.Set; public class Menu { /**
* 生成微信菜单请求方法
* @param request
* @param model
* @return
*/
@RequestMapping("/weixinMenu/o_menu.do")
public String menu(HttpServletRequest request, ModelMap model) {
List<WeixinMenu> menus =null; //获取菜单集合
String msg =createMenu(getMenuJsonString(menus));
try {
JSONObject object = new JSONObject(msg);
if (!object.get("errcode").equals("0")){
model.addAttribute("msg",msg);
//操作失败处理代码
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
} /**
* 创建自定义菜单
*/
public String createMenu(String menus){
String token=getToken();//获取access_token
String createMenuUrl="https://api.weixin.qq.com/cgi-bin/menu/create"; //微信提供的菜单接口地址
String url = createMenuUrl+"?access_token=" + token;
String msg = post(url, menus,"application/json");
return msg;
} /**
* 获取access_token
* @return
*/
public String getToken() {
String tokenGetUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";//微信提供获取access_token接口地址
String appid="";
String secret=""; System.out.println("~~~~~appid:"+appid);
System.out.println("~~~~~secret:"+secret);
JSONObject tokenJson=new JSONObject();
if(StringUtils.isNotBlank(appid)&&StringUtils.isNotBlank(secret)){
tokenGetUrl+="&appid="+appid+"&secret="+secret;
tokenJson=getUrlResponse(tokenGetUrl);
System.out.println("~~~~~tokenJson:"+tokenJson.toString());
try {
return (String) tokenJson.get("access_token");
} catch (JSONException e) {
System.out.println("报错了");
return null;
}
}else{
System.out.println("appid和secret为空");
return null;
}
} private JSONObject getUrlResponse(String url){
CharsetHandler handler = new CharsetHandler("UTF-8");
try {
HttpGet httpget = new HttpGet(new URI(url));
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//HttpClient
CloseableHttpClient client = httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client);
return new JSONObject(client.execute(httpget, handler));
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 将菜单集合转换为json数据
* @param menus
* @return
*/
public String getMenuJsonString(List<WeixinMenu> menus) { String strJson = "{" +
"\"button\":["; for (int i = 0; i < menus.size(); i++) {
strJson = strJson + "{ ";
WeixinMenu menu = menus.get(i);
if(menu.getChild().size()>0){
strJson = strJson +
"\"name\":\""+menu.getName()+"\","+
"\"sub_button\":[";
Set<WeixinMenu> sets = menu.getChild();
Iterator<WeixinMenu> iter = sets.iterator();
int no = 1;
while(iter.hasNext()){
if(no>5){
break;
}else{
if(no==1){
strJson = strJson + "{";
}else{
strJson = strJson + ",{";
}
WeixinMenu child = iter.next();
if(child.getType().equals("click")){
strJson = strJson +
"\"type\":\"click\","+
"\"name\":\""+child.getName()+"\","+
"\"key\":\""+child.getKey()+"\"}";
}else{
strJson = strJson +
"\"type\":\"view\","+
"\"name\":\""+child.getName()+"\","+
"\"url\":\""+child.getUrl()+"\"}";
}
no++;
}
}
strJson = strJson+"]";
}else if(menu.getType().equals("click")){
strJson = strJson +
"\"type\":\"click\","+
"\"name\":\""+menu.getName()+"\","+
"\"key\":\""+menu.getKey()+"\"";
}else{
strJson = strJson +
"\"type\":\"view\","+
"\"name\":\""+menu.getName()+"\","+
"\"url\":\""+menu.getUrl()+"\"";
}
if(i==menus.size()-1){
strJson = strJson + "}";
}else{
strJson = strJson + "},";
}
}
strJson = strJson + "]}";
return strJson; } /**
* 发送请求
* @param url 请求地址
* @param json 数据
* @param contentType 编码
* @return
*/
private String post(String url, String json,String contentType)
{
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//HttpClient
CloseableHttpClient client = httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client);
HttpPost post = new HttpPost(url);
try
{
StringEntity s = new StringEntity(json,"utf-8");
if(StringUtils.isBlank(contentType)){
s.setContentType("application/json");
}
s.setContentType(contentType);
post.setEntity(s);
HttpResponse res = client.execute(post);
HttpEntity entity = res.getEntity();
String str= EntityUtils.toString(entity, "utf-8");
return str;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
} private static HttpClient wrapClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLSv1");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
return httpclient; } catch (Exception ex) {
return null;
}
} private class CharsetHandler implements ResponseHandler<String> {
private String charset; public CharsetHandler(String charset) {
this.charset = charset;
} public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
if (entity != null) {
if (!StringUtils.isBlank(charset)) {
return EntityUtils.toString(entity, charset);
} else {
return EntityUtils.toString(entity);
}
} else {
return null;
}
}
} }

  

如果出现 {"errcode":40001,"errmsg":"invalid credential, hint:。。。

可能是需要把当前的ip地址加入到公众号的后台 IP白名单中JAVA微信公众号网页开发——生成自定义微信菜单(携带参数)