微信公众号自定义菜单
程序员文章站
2022-05-30 20:33:35
...
说明:有时候我们微信公众号后台启用了自己的开发者服务器,自定义菜单就不能通过微信公众号后台创建,这时候需要在服务器自己写创建菜单的方法。
1.注意事项
1、自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
2、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。
2.主要介绍自定义菜单是url链接式的和点击响应式的。
1、click:点击推事件用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;这个可以通过key值给用户返回文本信息或者推送消息等,如果菜单数据存在数据库表里面,key可当外键看待。
2、view:跳转URL用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。
3.接口
http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
4.请求的json串举例:本次创建菜单一级菜单两个,二级菜单三个
{ "button": [
{
"name": "政策快递",
"sub_button": [
{
"type": "view",
"name": "发票抽奖",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx5d822439132ee58a&redirect_uri=http%3a%2f%2f43.shung.com%2fxcgs%2fsxgs%2finvoiceinqurity%2fopenid.jsp&response_type=code&scope=snsapi_base&state=123#wechat_redirect"
}
]
},
{
"name": "咨询投诉",
"sub_button": [
{
"type": "view",
"name": "机构查询",
"url": "http://117.34.72.36/weixin/mobile/area/area.jsp"
},
{
"type": "click",
"name": "文件中心",
"key": "key001"
}
]
}
]}
5.调用返回参数说明:
参数
button: 一级菜单数组,个数应为1~3个
sub_button:二级菜单数组,个数应为1~5个
type : 菜单的响应动作类型,view表示网页类型,click表示点击类型,miniprogram表示小程序类型
name:菜单标题,不超过16个字节,子菜单不超过60个字节
key:菜单KEY值,用于消息接口推送,不超过128字节
url:网页链接,用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
6.返回结果
{"errcode":0,"errmsg":"ok"}
举例:java代码
package cn.com.zhongway.im.wechat;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
import org.apache.log4j.Logger;
import net.sf.json.JSONObject;
public class CreateMenu {
private static Logger logger = Logger.getLogger(CreateMenu.class.getName());
public static void main(String[] args) {
String appid = "wx5d822439132ee58a";
String secret = "hdujdjb2knk3nem3n333k3khn3nej342bjb";
//获取accessToken
String accessToken = getAccessToken(appid, secret);
//这里面的json就是菜单的json串,一般你先保存在数据库,从数据库取出来成json的形式传给接口如下文实例js的
//注意转移符 读者做的时候这个是自己动态拼写 别这样写
String json = "{"
+ " \"button\": [ "
+ " {"
+ " \"name\": \"政策快递\", "
+ " \"sub_button\": [ "
+ " { "
+ " \"type\": \"view\", "
+ " \"name\": \"发票抽奖\", "
+ " \"url\": \"https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx5d822439132ee58a&redirect_uri=http%3a%2f%2f43.shung.com%2fxcgs%2fsxgs%2finvoiceinqurity%2fopenid.jsp&response_type=code&scope=snsapi_base&state=123#wechat_redirect\" "
+ " } "
+ " ] "
+ " }, "
+ " { "
+ " \"name\": \"咨询投诉\", "
+ " \"sub_button\": [ "
+ " { "
+ " \"type\": \"view\", "
+ " \"name\": \"机构查询\", "
+ " \"url\": \"http://shuiqit/weixin/mobile/area/area.jsp\" "
+ " }, " + " { " + " \"type\": \"click\", "
+ " \"name\": \"文件中心\", " + " \"key\": \"key001\" "
+ " } "
+ " ] " + " } " + " ] " + " }";
sendMenuMsg(json, accessToken);
}
//创建菜单接口
private static JSONObject sendMenuMsg(String json, String ls_token) {
//创建菜单的接口
String _s_sendmsg_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token='"
+ ls_token + "'";
try {
JSONObject jsonobject = getData(_s_sendmsg_url, "POST", json);
//返回创建状态
return jsonobject;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//请求公众接口公用类可以写到自己的工具类自己调这演示放在一起拉
public static JSONObject getData(String requestUrl, String requestMethod,
String outputStr) throws Exception {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
HttpsURLConnection httpUrlConn = null;
InputStream inputStream = null;
BufferedReader bufferedReader = null;
InputStreamReader inputStreamReader = null;
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
X509TrustManager[] tm = { (X509TrustManager) new myX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, (javax.net.ssl.TrustManager[]) tm,
new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
// 当有数据需要提交时
if (null != outputStr) {
//logger.info("发送消息为:"+outputStr);
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
inputStream = httpUrlConn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "utf-8");
bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
logger.info(buffer.toString());
jsonObject = JSONObject.fromObject(buffer.toString().replace("'",
""));
} finally {
if (inputStream != null) {
inputStream.close();
inputStream = null;
}
if (httpUrlConn != null)
httpUrlConn.disconnect();
if (bufferedReader != null)
bufferedReader.close();
if (inputStreamReader != null)
inputStreamReader.close();
}
return jsonObject;
}
//获取access_token
public static String getAccessToken(String appid, String secret) {
String access_token = "";
String grant_type = "client_credential";//获取access_token填写client_credential
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="
+ grant_type + "&appid=" + appid + "&secret=" + secret;
//这个url链接地址和参数皆不能变
String requestUrl = "";
String oppid = "";
JSONObject oppidObj = null;
String openid = "";
String requestUrl2 = "";
String userInfoStr = "";
JSONObject wxUserInfo = null;
try {
//获取code后,请求以下链接获取access_token
URL urlGet = new URL(url);
HttpURLConnection http = (HttpURLConnection) urlGet
.openConnection();
http.setRequestMethod("GET"); // 必须是get方式请求
http.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
http.connect();
InputStream is = http.getInputStream();
int size = is.available();
byte[] jsonBytes = new byte[size];
is.read(jsonBytes);
String message = new String(jsonBytes, "UTF-8");
JSONObject demoJson = JSONObject.fromObject(message);
System.out.println("JSON字符串:" + demoJson);
access_token = demoJson.getString("access_token");
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return access_token;
}
}
7.http传输安全通信辅助类
package cn.com.zhongway.im.wechat;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
//创建SSLContext对象,并使用我们指定的信任管理器初始化
public class myX509TrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
基本的流程就这样!可根据自己的实现改,菜单的具体内容,读者可以自己放自己数据库,APPID等微信参数读者自己根据自己的微信公众号设置。
结果:
下一篇: 微信公众号(消息回复)