微信开发二 : 自定义菜单
来源:互联网 发布:cctv视频下载软件 编辑:程序博客网 时间:2024/04/30 15:39
自定义菜单基本介绍:
目前自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。请注意,创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现出来。建议测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
目前自定义菜单接口可实现两种类型按钮,如下:
click:用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;view:用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的url值(即网页链接),达到打开网页的目的,建议与网页授权获取用户基本信息接口结合,获得用户的登入个人信息。
接口调用请求说明
http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
自定义菜单的请求是一个json格式的请求内容
官网的请求示例
{ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "type":"click", "name":"歌手简介", "key":"V1001_TODAY_SINGER" }, { "name":"菜单", "sub_button":[ { "type":"view", "name":"搜索", "url":"http://www.soso.com/" }, { "type":"view", "name":"视频", "url":"http://v.qq.com/" }, { "type":"click", "name":"赞一下我们", "key":"V1001_GOOD" }] }] }
参数说明
返回结果
正确时的返回JSON数据包如下:
{"errcode":0,"errmsg":"ok"}
错误时的返回JSON数据包如下(示例为无效菜单名长度):
{"errcode":40018,"errmsg":"invalid button name size"}
首先是菜单项的基类,所有一级菜单、二级菜单都共有一个相同的属性,那就是name。菜单项基类的封装代码如下:
package org.liufeng.weixin.pojo;/** * 按钮的基类 * * @author liufeng * @date 2013-08-08 */public class Button {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}
接着是子菜单项的封装。这里对子菜单是这样定义的:没有子菜单的菜单项,有可能是二级菜单项,也有可能是不含二级菜单的一级菜单。这类子菜单项一定会包含三个属性:type、name和key,封装的代码如下:
package org.liufeng.weixin.pojo;/** * 普通按钮(子按钮) * * @author liufeng * @date 2013-08-08 */public class CommonButton extends Button {private String type;private String key;public String getType() {return type;}public void setType(String type) {this.type = type;}public String getKey() {return key;}public void setKey(String key) {this.key = key;}}
再往下是父菜单项的封装。对父菜单项的定义:包含有二级菜单项的一级菜单。这类菜单项包含有二个属性:name和sub_button,而sub_button以是一个子菜单项数组。父菜单项的封装代码如下:
package org.liufeng.weixin.pojo;/** * 复杂按钮(父按钮) * * @author liufeng * @date 2013-08-08 */public class ComplexButton extends Button {private Button[] sub_button;public Button[] getSub_button() {return sub_button;}public void setSub_button(Button[] sub_button) {this.sub_button = sub_button;}}
最后是整个菜单对象的封装,菜单对象包含多个菜单项(最多只能有3个),这些菜单项即可以是子菜单项(不含二级菜单的一级菜单),也可以是父菜单项(包含二级菜单的菜单项),如果能明白上面所讲的,再来看封装后的代码就很容易理解了:
package org.liufeng.weixin.pojo;/** * 菜单 * * @author liufeng * @date 2013-08-08 */public class Menu {private Button[] button;public Button[] getButton() {return button;}public void setButton(Button[] button) {this.button = button;}}
关于POJO类的封装就介绍完了
/** * 组装菜单数据 * * @return */private static Menu getMenu() {CommonButton btn11 = new CommonButton();btn11.setName("天气预报");btn11.setType("click");btn11.setKey("11");CommonButton btn12 = new CommonButton();btn12.setName("公交查询");btn12.setType("click");btn12.setKey("12");CommonButton btn13 = new CommonButton();btn13.setName("周边搜索");btn13.setType("click");btn13.setKey("13");CommonButton btn14 = new CommonButton();btn14.setName("历史上的今天");btn14.setType("click");btn14.setKey("14");CommonButton btn21 = new CommonButton();btn21.setName("歌曲点播");btn21.setType("click");btn21.setKey("21");CommonButton btn22 = new CommonButton();btn22.setName("经典游戏");btn22.setType("click");btn22.setKey("22");CommonButton btn23 = new CommonButton();btn23.setName("美女电台");btn23.setType("click");btn23.setKey("23");CommonButton btn24 = new CommonButton();btn24.setName("人脸识别");btn24.setType("click");btn24.setKey("24");CommonButton btn25 = new CommonButton();btn25.setName("聊天唠嗑");btn25.setType("click");btn25.setKey("25");CommonButton btn31 = new CommonButton();btn31.setName("Q友圈");btn31.setType("click");btn31.setKey("31");CommonButton btn32 = new CommonButton();btn32.setName("电影排行榜");btn32.setType("click");btn32.setKey("32");CommonButton btn33 = new CommonButton();btn33.setName("幽默笑话");btn33.setType("click");btn33.setKey("33");ComplexButton mainBtn1 = new ComplexButton();mainBtn1.setName("生活助手");mainBtn1.setSub_button(new CommonButton[] { btn11, btn12, btn13, btn14 });ComplexButton mainBtn2 = new ComplexButton();mainBtn2.setName("休闲驿站");mainBtn2.setSub_button(new CommonButton[] { btn21, btn22, btn23, btn24, btn25 });ComplexButton mainBtn3 = new ComplexButton();mainBtn3.setName("更多体验");mainBtn3.setSub_button(new CommonButton[] { btn31, btn32, btn33 });/** * 这是公众号xiaoqrobot目前的菜单结构,每个一级菜单都有二级菜单项<br> * * 在某个一级菜单下没有二级菜单的情况,menu该如何定义呢?<br> * 比如,第三个一级菜单项不是"更多体验",而直接是"幽默笑话",那么menu应该这样定义:<br> * menu.setButton(new Button[] { mainBtn1, mainBtn2, btn33 }); */Menu menu = new Menu();menu.setButton(new Button[] { mainBtn1, mainBtn2, mainBtn3 });return menu;}}
通过json格式创建菜单
package controllers;import org.apache.log4j.Logger;import com.star.wxservice.MenuService;import com.star.wxservice.baseservice;import com.star.wxservice.impl.MenuServiceImpl;public class WXMenuController extends ApplicationController { baseservice baseservice = new baseservice(); MenuService menuService = new MenuServiceImpl(); private static Logger logger = Logger.getLogger(DrpController.class); /** * 微信菜单 * * @return */ public static String getJsonMenu() { // baseservice.BuildAuthCallbackUrl("需要授权的URL地址",EnumScopeType.snsapi_userinfo); StringBuilder jsonMenu = new StringBuilder(); jsonMenu.append("{\"button\":["); jsonMenu.append("{\"name\":\"主菜单一\",\"sub_button\":["); jsonMenu.append("{\"type\":\"click\",\"name\":\"输入1\",\"key\":\"M1001\"},"); jsonMenu.append("{\"type\":\"view\",\"name\":\"搜搜\",\"url\":\"http://www.soso.com/\"}]},"); jsonMenu.append("{\"type\":\"click\",\"name\":\"主菜单二\",\"key\":\"M2001\"},"); jsonMenu.append("{\"type\":\"click\",\"name\":\"主菜单三\",\"key\":\"M3001\"}"); jsonMenu.append("]}"); return jsonMenu.toString(); } /** * 自定义微信菜单 * * 1、自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。 * 2、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。 * 3、创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。 * * @return * @throws Exception */ public String CreateMenu() throws Exception { String jsonMenu = getJsonMenu(); String strjson = ""; try { strjson = menuService.CreateMenu(jsonMenu); } catch (Exception e) { logger.error("创建菜单失败" + e); e.printStackTrace(); } return strjson; } /** * 使用接口创建自定义菜单后,开发者还可使用接口删除当前使用的自定义菜单。另请注意,在个性化菜单时,调用此接口会删除默认菜单及全部个性化菜单。 * * @return */ public String DeleteMenu() { String strjson = menuService.DeleteMenu(); return strjson; }}
package com.star.wxservice.impl;import org.apache.log4j.Logger;import com.star.utils.HttpRequestUtil;import com.star.wxservice.MenuService;import com.star.wxservice.baseservice;import controllers.DrpController;import net.sf.json.JSONObject;public class MenuServiceImpl implements MenuService { baseservice baseservice = new baseservice(); private static Logger logger = Logger.getLogger(DrpController.class); // 菜单创建(POST) 限100(次/天) public static String MENU_CREATE = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN"; // 删除当前使用的自定义菜单 public static String MENU_DELETE = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN"; public String CreateMenu(String jsonMenu) { String resultStr = ""; // 调用接口获取token String token = null; try { token = baseservice.GetAccessToken(); } catch (Exception e) { logger.error("菜单创建获取token异常"); // TODO Auto-generated catch block e.printStackTrace(); } if (token != null) { // 调用接口创建菜单 int result = createMenu(jsonMenu, token); // 判断菜单创建结果 if (0 == result) { resultStr = "菜单创建成功"; logger.info(resultStr); } else { resultStr = "菜单创建失败,错误码:" + result; logger.error(resultStr); } } return resultStr; } /** * 创建菜单 * * @param jsonMenu * 菜单的json格式 * @param accessToken * 有效的access_token * @return 0表示成功,其他值表示失败 */ public static int createMenu(String jsonMenu, String accessToken) { int result = 0; // 拼装创建菜单的url String url = MENU_CREATE.replace("ACCESS_TOKEN", accessToken); // 调用接口创建菜单 String strjson = HttpRequestUtil.httpRequest(url, jsonMenu, "POST"); JSONObject jsonObject = JSONObject.fromObject(strjson); if (null != jsonObject) { if (0 != jsonObject.getInt("errcode")) { result = jsonObject.getInt("errcode"); logger.error( "创建菜单失败 errcode:" + jsonObject.getInt("errcode") + ",errmsg:" + jsonObject.getString("errmsg")); } } return result; } /** * 删除默认菜单及全部个性化菜单。 * * @return */ public String DeleteMenu() { String token = null; try { token = baseservice.GetAccessToken(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } String url = MENU_DELETE.replace("ACCESS_TOKEN", token); String strjson = HttpRequestUtil.httpRequest(url, "", "GET"); return strjson; }}
部分转载于:http://www.5icool.org/a/201308/a2152_2.html
- 微信开发(二)自定义菜单
- 微信开发二 : 自定义菜单
- 微信公众号的开发之 自定义菜单(二)
- 微信开发 -- 自定义菜单
- 微信开发-自定义菜单
- 微信开发--自定义菜单
- 微信自定义菜单开发
- 微信开发自定义菜单
- 二十四:微信公众帐号开发-自定义菜单的创建及菜单事件响应
- 微信/易信公共平台开发(二):自定义菜单的PHP实现(提供源码)
- Servlet--微信自定义菜单(二)
- 微信自定义菜单开发报错
- php微信自定义菜单开发
- 微信公众平台自定义菜单开发
- 微信开发二三事:自定义菜单
- 微信企业号开发:自定义菜单
- 微信开发(1)自定义菜单
- java微信开发自定义菜单
- activity中与taskAffinity,allowTaskReparenting,启动模式相关的问题
- 6.2分鱼问题
- leetcode-42. Trapping Rain Water
- input type="submit" 和"button"有什么区别?
- 游戏大数据分析--游戏玩家
- 微信开发二 : 自定义菜单
- ViewPage中自定义标题栏(四)
- 红黑树-TreeMap
- 二叉排序查找树
- ROS学习历程(5)-----在工作空间中构建和使用catkin包
- android edittext切换编辑状态
- SSL P1618 剑鱼行动
- 11.30 install caffe
- Altium Designer 10 介绍、原理图及其模板常规设计