官网接口地址: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微信公众号网页开发——生成自定义微信菜单(携带参数)的更多相关文章

  1. 你所误解的微信公众号开发、以及微信公众号网页授权、接收url跳转参数等问题

    前言:有一星期没跟新博客了,最近太忙.项目赶进度就没把时间花在博客上:今天来说说所谓的微信公众号开发和填坑记录: 微信公众号:运行在微信终端的应用 (对于开发者来说比较爽的你只需考虑兼容微信浏览器,因 ...

  2. JAVA微信公众号网页开发 —— 用户授权获取openid

    官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842 HttpClientUtil.java packa ...

  3. JAVA微信公众号网页开发——获取公众号关注的所有用户(微信公众号粉丝)

    package com.weixin.sendmessage; import org.apache.commons.lang.StringUtils; import org.apache.http.H ...

  4. JAVA微信公众号网页开发——将接收的消息转发到微信自带的客服系统

    如果公众号处于开发模式,普通微信用户向公众号发消息时,微信服务器会先将消息POST到开发者填写的url上,无法直接推送给微信自带的客服功能.如果需要把用户推送的普通消息推送到客服功能中,就需要进行代码 ...

  5. 微信公众号第三方平台生成自定义菜单提示 获取"access_token失败"

    在微信公众号第三方平台要生成自定义菜单时,程序反应很慢,最终提示"获取access_token失败"(之前程序无改动,使用时间已久),查了大半天,找不出原因. 排除.在微信公众号平 ...

  6. 微信公众号网页开发-jssdk config配置参数生成(Java版)

    一.配置参数 参考官方文档:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&la ...

  7. JAVA微信公众号网页开发 —— 接收微信服务器发送的消息

    WeixinMessage.java package com.test; import java.io.Serializable; /** * This is an object that conta ...

  8. JAVA微信公众号网页开发——通过接收人的openid发送模板消息

    TemplateData.java 1 package com.weixin.weixin.template; 2 3 public class TemplateData { 4 private St ...

  9. C#开发微信公众号——网页开发之微信网页授权

    首先咱们先看下公众号的文档里面的介绍 上述图片的文字描述就是讲述了网页授权有什么用,就是为了获取微信用户的基本信息:授权回调域名的规范,说到域名回调的事情就不得不提一下设置网页授权域名 最好将这三个域 ...

随机推荐

  1. Atcoder Grand Contest 020 E - Encoding Subsets(记忆化搜索+复杂度分析)

    Atcoder 题面传送门 & 洛谷题面传送门 首先先考虑如果没有什么子集的限制怎样计算方案数.明显就是一个区间 \(dp\),这个恰好一年前就做过类似的题目了.我们设 \(f_{l,r}\) ...

  2. dotnet 将自动代码格式化机器人带入团队 GitLab 平台

    给团队带入一个 代码格式化机器人 能提升团队的幸福度,让团队的成员安心写代码,不用关注代码格式化问题,将格式代码这个粗活交给机器人去做.同时也能减少在代码审查里撕格式化问题的时间,让更多的时间投入到更 ...

  3. R包xlsx安装与使用

     1. Rstudio安装xlsx报错 xlsx包加载依赖Java环境,我之前就安装过Java,但安装xlsx成功后,加载xlsx时一直报错: Error : loadNamespace()里算'rJ ...

  4. python20判断变量是否存在

    python中检测某个变量是否有定义 第一种方法使用内置函数locals(): locals():获取已定义对象字典 'testvar' in locals().keys() 第二种方法使用内置函数d ...

  5. 63. Binary Tree Level Order Traversal II

    Binary Tree Level Order Traversal II My Submissions QuestionEditorial Solution Total Accepted: 79742 ...

  6. C7的开机自启动设置

    CentOS 7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统(system)和用户(user)之分 系统服务放在/usr/lib/systemd/system [Un ...

  7. oracle 将电话号码中间4位数以星号*代替

    select replace('17665312355',substr('17665312355',4,4),'****')  as phone,                       #类似E ...

  8. kubernetes部署 docker 容器

    docker 容器相对比较简单,不涉及认证授权,只需要本地启动起来即可,唯一需要注意就是添加flannel网络. # yum remove docker-latest-logrotate docker ...

  9. 日常Java测试 2021/11/14

    课堂测试三 package word_show; import java.io.*;import java.util.*;import java.util.Map.Entry; public clas ...

  10. apostrophe

    apostrophe 者,', 0x27, 十进制39,ASCII里的single quote (单引号) 也.one of the 'inverted commas'. 在书写上可以表示所有格.省略 ...