先上效果图
这个是我自定义的菜单,在微信开发者文档中需要用到https协议进行更改,且更改次数有限制,如下
接口名称频率限制获取凭证接口200(次/天)
自定义菜单创建接口100(次/天)
自定义菜单查询接口1000(次/天)
自定义菜单删除接口100(次/天)
了解完上述需要注意到的实例后,接下我们在来看看创建接口时所需要的参数,如图所示:
一般的请求格式如下代码所示:
{
"button":[
{
"type":"click",
"name":"今日歌曲",
"key":"V1001_TODAY_MUSIC"
},
{
"name":"菜单",
"sub_button":[
{
"type":"view",
"name":"搜索",
"url":"http://www.soso.com/"
},
{
"type":"miniprogram",
"name":"wxa",
"url":"http://mp.weixin.qq.com",
"appid":"wx286b93c14bbf93aa",
"pagepath":"pages/lunar/index"
},
{
"type":"click",
"name":"赞一下我们",
"key":"V1001_GOOD"
}]
}]
}
接口调用请求说明
http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
以上实现的是一个二级菜单,点击按钮跳转页面的功能,接下来我们来看看代码怎么实现。
创建菜单
public static void createMenu(String appId,String appSecret) {
// 调用接口获取access_token
AccessToken at = WeixinUtil.getAccessToken(appId, appSecret);
if (null != at) {
// 调用接口创建菜单
int result = WeixinUtil.createMenu(getMenu(), at.getToken());
// 判断菜单创建结果
if (0 == result)
System.out.print("菜单创建成功!");
else
System.out.print("菜单创建失败,错误码:" + result);
}
String jsonMenu = JSONObject.toJSONString(getMenu());
System.out.print(jsonMenu);
}
private static Button getMenu() {
String APPID = "填你自己的";
String REDIRECT_URI = "http://rpaize.natappfree.cc/WeChatProject/wechat/hello";
String urlscope = "snsapi_userinfo";
String state = "1";
BaseButton btn11 = new BaseButton();
btn11.setName("学霸笔记本");
btn11.setType("click");
btn11.setKey("11");
BaseButton btn12 = new BaseButton();
btn12.setName("记忆宫殿");
btn12.setType("click");
btn12.setKey("12");
BaseButton btn13 = new BaseButton();
btn13.setName("逻辑思维");
btn13.setType("view");
StringBuilder url = new StringBuilder();
url.append("https://open.weixin.qq.com/connect/oauth2/authorize?");
url.append("appid="+APPID);
url.append("&");
url.append("redirect_uri="+REDIRECT_URI);
url.append("&");
url.append("response_type=code");
url.append("&");
url.append("scope="+urlscope);
url.append("&state=1#wechat_redirect");
btn13.setUrl(url.toString());
Sub_Button sub1 = new Sub_Button();
sub1.setName("菜单一");
sub1.getSub_button().add(btn11);
Sub_Button sub2 = new Sub_Button();
sub2.setName("菜单二");
sub2.getSub_button().add(btn12);
Sub_Button sub3 = new Sub_Button();
sub3.setName("xinbuxing");
sub3.getSub_button().add(btn13);
Button menu = new Button();
menu.getButton().add(sub1);
menu.getButton().add(sub2);
menu.getButton().add(sub3);
return menu;
}
按钮采用fastjson解析
Button.java
/**
* Created by mianhai on 2017/4/19.
*/
public class Button {
private List<Sub_Button> button = new ArrayList<Sub_Button>();
public List<Sub_Button> getButton() {
return button;
}
public void setButton(List<Sub_Button> button) {
this.button = button;
}
}
BaseButton.java
/**
* Created by mianhai on 2017/4/19.
*/
public class BaseButton {
private String type;
private String name;
private String key;
private String url;
private String appid;
private String pagepath;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getPagepath() {
return pagepath;
}
public void setPagepath(String pagepath) {
this.pagepath = pagepath;
}
}
Sub_Button.java
public class Sub_Button {
List< BaseButton> sub_button = new ArrayList<BaseButton>();
private String type;
private String name;
private String key;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public List<BaseButton> getSub_button() {
return sub_button;
}
public void setSub_button(List<BaseButton> sub_button) {
this.sub_button = sub_button;
}
}
WeixinUtil.java
public class WeixinUtil {
// 获取access_token的接口地址(GET) 限200(次/天)
public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
// 菜单创建(POST) 限100(次/天)
public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
/**
* 发起https请求并获取结果
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @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);
// 设置请求方式(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 = JSON.parseObject(buffer.toString());
System.out.print(jsonObject);
} catch (ConnectException ce) {
} catch (Exception e) {
}
return jsonObject;
}
public static AccessToken getAccessToken(String appid, String appsecret) {
AccessToken accessToken = null;
String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
accessToken = new AccessToken();
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getIntValue("expires_in"));
} catch (JSONException e) {
accessToken = null;
// 获取token失败
}
}
return accessToken;
}
/**
* 创建菜单
*
* @param menu 菜单实例
* @param accessToken 有效的access_token
* @return 0表示成功,其他值表示失败
*/
public static int createMenu(Button menu, String accessToken) {
int result = 0;
// 拼装创建菜单的url
String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);
// 将菜单对象转换成json字符串
String jsonMenu = JSONObject.toJSONString(menu);
// 调用接口创建菜单
JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);
if (null != jsonObject) {
if (0 != jsonObject.getIntValue("errcode")) {
result = jsonObject.getIntValue("errcode");
}
}
return result;
}
}
接着只要在我们的main方法中跑一跑,再重新关注一下就可以了,注意我用的是测试号,订阅号好像没用开放这个权限