微信开发二 : 自定义菜单

来源:互联网 发布: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



0 0
原创粉丝点击