JAVA微信公众号网页开发——生成自定义微信菜单(携带参数)
官网接口地址: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微信公众号网页开发——生成自定义微信菜单(携带参数)的更多相关文章
- 你所误解的微信公众号开发、以及微信公众号网页授权、接收url跳转参数等问题
前言:有一星期没跟新博客了,最近太忙.项目赶进度就没把时间花在博客上:今天来说说所谓的微信公众号开发和填坑记录: 微信公众号:运行在微信终端的应用 (对于开发者来说比较爽的你只需考虑兼容微信浏览器,因 ...
- JAVA微信公众号网页开发 —— 用户授权获取openid
官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842 HttpClientUtil.java packa ...
- JAVA微信公众号网页开发——获取公众号关注的所有用户(微信公众号粉丝)
package com.weixin.sendmessage; import org.apache.commons.lang.StringUtils; import org.apache.http.H ...
- JAVA微信公众号网页开发——将接收的消息转发到微信自带的客服系统
如果公众号处于开发模式,普通微信用户向公众号发消息时,微信服务器会先将消息POST到开发者填写的url上,无法直接推送给微信自带的客服功能.如果需要把用户推送的普通消息推送到客服功能中,就需要进行代码 ...
- 微信公众号第三方平台生成自定义菜单提示 获取"access_token失败"
在微信公众号第三方平台要生成自定义菜单时,程序反应很慢,最终提示"获取access_token失败"(之前程序无改动,使用时间已久),查了大半天,找不出原因. 排除.在微信公众号平 ...
- 微信公众号网页开发-jssdk config配置参数生成(Java版)
一.配置参数 参考官方文档:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&la ...
- JAVA微信公众号网页开发 —— 接收微信服务器发送的消息
WeixinMessage.java package com.test; import java.io.Serializable; /** * This is an object that conta ...
- JAVA微信公众号网页开发——通过接收人的openid发送模板消息
TemplateData.java 1 package com.weixin.weixin.template; 2 3 public class TemplateData { 4 private St ...
- C#开发微信公众号——网页开发之微信网页授权
首先咱们先看下公众号的文档里面的介绍 上述图片的文字描述就是讲述了网页授权有什么用,就是为了获取微信用户的基本信息:授权回调域名的规范,说到域名回调的事情就不得不提一下设置网页授权域名 最好将这三个域 ...
随机推荐
- CF1574D The Strongest Build
考虑到有\(m\)个限制,可以考虑\(m+1\)个最大的答案,这样可以利用鸽笼原理得到答案. 这是一般做法. 但是这样的题目,我们发现\(n\)个操作都是独立的. 那么我们可以全部都选取最大,并以此调 ...
- c++STL容器之string容器
本质:string是c++风格的字符串,而string本质上是一个类 string和char*的区别: char*是一个指针: string是一个类,类内部封装了char*,管理这个字符串,是一个ch ...
- [Linux]非root的R环境被conda破坏后如何恢复?
记录说明 这篇文章本来是用来记录Linux非root环境下安装PMCMRplus包折腾过程,但后来试过了各种方法安装不上这个R包后,我换上了Miniconda来安装.经前人提醒,一开始安装Minico ...
- shell 脚本自动插入文件头
vim编辑shell脚本自动插入文件头部信息,将下面的代码写入home目录xia .vimrc 文件即可. shell 文件头: 1 autocmd BufNewFile *.sh exec &quo ...
- Browse Code Answers
一个记录各种语言可能遇到的问题的论坛 :https://www.codegrepper.com/code-examples/
- 55. Binary Tree Preorder Traversal
Binary Tree Preorder Traversal My Submissions QuestionEditorial Solution Total Accepted: 119655 Tota ...
- memset初始化值的效率秒杀for循环
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255) ...
- 再聊我们自研的那些Devops工具
两年前我写了篇文章『我们自研的那些Devops工具』介绍了我们自研的一些DevOps工具系统,两年过去了这些工具究竟还有没有在发光发热,又有哪些新的变化呢,我将通过这篇文章来回顾一下这两年的发展与变化 ...
- 同一局域网,远程连接别人的Mysql数据库
数据库:MySQL 工具: Navicat, 电脑A连接电脑B的数据库, 确保两部电脑都是在同一个局域网,都是连着同一个路由器,或者连接同一个WiFi, 如果不确定是否为同一个局域网,可以打开cmd, ...
- PC端申请表
公司项目需求中要做用html做一个PDF申请表的样式出来.有点意思,贴上来大家看看. 先上效果图: 附上源代码: HTML:<div id="form"> <h2 ...