• 说明
  • 菜单数据库表设计
  • 菜单数据拼装与发布
    • 数据拼装和接口调用
    • Mapper设计
  • 效果展示

说明

自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能。开启自定义菜单后,公众号界面如图所示:

微信接入后台后,须注意,这时发布菜单是必须进行的一步

请注意:
1、自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
2、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“…”代替。
3、创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
自定义菜单接口可实现多种类型按钮,如下:
1、click:点击推事件用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;
2、view:跳转URL用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。
3、scancode_push:扫码推事件用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后显示扫描结果(如果是URL,将进入URL),且会将扫码的结果传给开发者,开发者可以下发消息。
4、scancode_waitmsg:扫码推事件且弹出“消息接收中”提示框用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。
5、pic_sysphoto:弹出系统拍照发图用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。
6、pic_photo_or_album:弹出拍照或者相册发图用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。
7、pic_weixin:弹出微信相册发图器用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。
8、location_select:弹出地理位置选择器用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。
9、media_id:下发消息(除文本消息)用户点击media_id类型按钮后,微信服务器会将开发者填写的永久素材id对应的素材下发给用户,永久素材类型可以是图片、音频、视频、图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
10、view_limited:跳转图文消息URL用户点击view_limited类型按钮后,微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL,永久素材类型只支持图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
接口调用请求说明
http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
以上来自微信公众平台开发文档

菜单数据库表设计

参数说明
参数 是否必须 说明
button 是 一级菜单数组,个数应为1~3个
sub_button 否 二级菜单数组,个数应为1~5个
type 是 菜单的响应动作类型,view表示网页类型,click表示点击类型,miniprogram表示小程序类型
name 是 菜单标题,不超过16个字节,子菜单不超过60个字节
key click等点击类型必须 菜单KEY值,用于消息接口推送,不超过128字节
url view、miniprogram类型必须 网页 链接,用户点击菜单可打开链接,不超过1024字节。 type为miniprogram时,不支持小程序的老版本客户端将打开本url。
media_id media_id类型和view_limited类型必须 调用新增永久素材接口返回的合法media_id
appid miniprogram类型必须 小程序的appid(仅认证公众号可配置)
pagepath miniprogram类型必须 小程序的页面路径

{"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"}]}]}
//根据微信参数说明和demo我们进行菜单表设计。
DROP TABLE IF EXISTS `t_weixin_menu`;
CREATE TABLE `t_weixin_menu` (`id` int(14) NOT NULL AUTO_INCREMENT,`content` varchar(100) DEFAULT NULL COMMENT '内容',`menu_key` varchar(50) DEFAULT NULL COMMENT '键值',`name` varchar(50) DEFAULT NULL COMMENT '名称',`pid` int(2) DEFAULT NULL COMMENT '父菜单id',`respon_type` int(2) DEFAULT NULL COMMENT '响应',`type` varchar(50) DEFAULT NULL COMMENT '菜单类型',`url` varchar(200) DEFAULT NULL COMMENT 'url',`isoauth` int(1) NOT NULL DEFAULT '0' COMMENT '是否授权',`wxsystoken` varchar(64) NOT NULL DEFAULT 'C9A58DA3804E46981BF4B78C8C862743' COMMENT '公众号系统token',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

菜单数据拼装与发布

数据拼装和接口调用

package com.lh.wx.service;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.inject.Inject;import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;import com.alibaba.fastjson.JSONObject;
import com.lh.message.Message;
import com.lh.message.util.MessageUtil;
import com.lh.wx.dao.WeixinMenuMapper;
import com.lh.wx.model.WeixinMenu;
import com.lh.wx.model.WeixinMenuDto;
import com.bigbigbu.wx.tools.api.WxConsts;
import com.bigbigbu.wx.tools.api.WxService;/**
* <p>Title: WechatMenuService</p>
* <p>Description: 微信菜单</p>
* <p>Company: DINGGE</p>
* @author    FANQIBU
* @date       2017年11月27日
*/
@Service
public class WechatMenuService {private @Inject WxService wxService;private @Inject WeixinMenuMapper mapper;private  @Inject  Environment  environment;private @Inject WechatService wechatService;/*** <p>Title: generateWeixinMenuDto</p>* <p>Description: 拼装菜单List</p>* @return*/public List<WeixinMenuDto> generateWeixinMenuDto(String wxsystoken) {/**** 动态加载公众号菜单*/List<WeixinMenu> menus=mapper.listGzAllByWxsystoken(wxsystoken);if(menus == null || menus.size() < 1){return null;}//List<WeixinMenu> menus=mapper.listAll();List<WeixinMenuDto> menuDtos=new ArrayList<WeixinMenuDto>();WeixinMenuDto wmd=null;for (WeixinMenu wm: menus) {wmd=new WeixinMenuDto(); wmd.setKey(wm.getMenuKey());wmd.setName(wm.getName());wmd.setType(wm.getType());wmd.setId(wm.getId());if(wm.getIsoauth() == 1){      //当菜单类型为view时,并且授权字段值==1时,进行拼装授权链接          wmd.setUrl(wxService.oauth2buildAuthorizationUrl(environment.getProperty("wx.redirect.uri")+"?wxsystoken="+environment.getProperty("wx.wxsystoken"), "snsapi_base",wm.getUrl()));}else{wmd.setUrl(wm.getUrl());}if(wm.getPid()==null||wm.getPid()==0){if(wmd.getSub_button()==null){wmd.setSub_button(new ArrayList<WeixinMenuDto>());}menuDtos.add(wmd);}else{WeixinMenuDto dto=findById(wm.getPid(), menuDtos);if(dto==null) throw new RuntimeException("菜单父类对象未找到请检查 ");dto.getSub_button().add(wmd);}}return menuDtos;}//根据父菜单id查询子菜单private WeixinMenuDto findById(Integer id,List<WeixinMenuDto> menuDtos){for (WeixinMenuDto weixinMenuDto : menuDtos) {if(id==weixinMenuDto.getId()){return weixinMenuDto;}}return null;}/*** <p>Title: publishMenu</p>* <p>Description: 发布微信菜单</p>* @return*/public Message<String> publishMenu(String wxsystoken) {int code=1002;String msg="发布成功!";String result=null;try {String url = WxConsts.URL_CREATE_MENU.replace("ACCESS_TOKEN",wxService.getAccessToken());List<WeixinMenuDto> wmds=generateWeixinMenuDto(wxsystoken );if(wmds == null || wmds.size() <1 ){return MessageUtil.getMessage(null, -1019, "未查询到菜单信息", "");}Map<String, List<WeixinMenuDto>> maps=new HashMap<String, List<WeixinMenuDto>>();maps.put("button", wmds);String json=JSONObject.toJSONString(maps);if (wechatService.loadWxSysConfigure(wxsystoken, true)) {result=wxService.post(url, json);JSONObject jsonObject=JSONObject.parseObject(result);if(jsonObject.getInteger("errcode") != 0){code=jsonObject.getInteger("errcode");msg=jsonObject.getString("errmsg");}}} catch (Exception e) {e.printStackTrace();code=-6666;msg="服务器开小差啦!";}return MessageUtil.getMessage(result, code, msg, "");}
}

Mapper设计

    <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.lh.wx.dao.WeixinMenuMapper" ><resultMap id="BaseResultMap" type="com.lh.wx.model.WeixinMenu" ><id column="id" property="id" jdbcType="INTEGER" /><result column="name" property="name" jdbcType="VARCHAR" /><result column="content" property="content" jdbcType="VARCHAR" /><result column="url" property="url" jdbcType="VARCHAR" /><result column="menu_key" property="menuKey" jdbcType="VARCHAR" /><result column="pid" property="pid" jdbcType="INTEGER" /><result column="type" property="type" jdbcType="VARCHAR" /><result column="respon_type" property="responType" jdbcType="INTEGER" /><result column="isoauth" property="isoauth" jdbcType="INTEGER" /><result column="wxsystoken" property="wxsystoken" jdbcType="VARCHAR" /></resultMap><select id="selectTalCount" resultType="java.lang.Integer">select count(id) from t_weixin_menu</select><select id="listPaging" resultMap="BaseResultMap" parameterType="com.lh.wx.model.WeixinMenuCustom">select * from t_weixin_menu <where><if test="name!=null">name like #{name}</if></where>limit #{start},#{end}</select>       <select id="listAll" resultMap="BaseResultMap">select * from t_weixin_menu</select><select id="listGzAllByWxsystoken" resultMap="BaseResultMap" parameterType="java.lang.String">SELECT * FROM t_weixin_menu WHERE wxsystoken = #{wxsystoken}</select><sql id="Base_Column_List">id,content,menu_key,name,pid,respon_type,type,url,isoauth,wxsystoken</sql>
</mapper>
package com.lh.wx.dao;import java.util.List;import com.lh.wx.model.WeixinMenu;
import com.lh.wx.model.WeixinMenuCustom;/**
* <p>Title: WeixinMenuMapper</p>
* <p>Description: 公众号菜单数据操作</p>
* <p>Company: DINGGE</p>
* @author    FANQIBU
* @date       2017年12月21日
*/
public interface WeixinMenuMapper {public List<WeixinMenu> listAll();/*** <p>Title: listGzAllByWxsystoken</p>* <p>Description: 根据公众号系统token查询公众号菜单</p>* @param wxsystoken* @return*/public List<WeixinMenu> listGzAllByWxsystoken(String wxsystoken);
}

效果展示

JAVA微信公众号开发第5篇菜单发布相关推荐

  1. JAVA微信公众号开发第8篇JSSDK图片上传预览

    简介 博主微信JSSDK&图片上传预览基于微信分享做拓展,所以一些配置操作请点击查阅JAVA微信公众号开发第7篇JSSDK&微信分享博文 页面 <html><head ...

  2. Java微信公众号开发微信网页授权之前端传递code方式获取用户信息

    本片博客讲解的网页授权分为两步,前端先传递backUrl(回调地址)到后台网页授权接口,该接口拿到回调地址后组装授权连接,重定向到前端页面,前端页面截取Code,传入后端获取用户信息方法,获取用户信息 ...

  3. 慕课网_《Java微信公众号开发进阶》学习总结

    时间:2017年08月12日星期六 说明:本文部分内容均来自慕课网.@慕课网:http://www.imooc.com 教学源码:http://img.mukewang.com/down/... 学习 ...

  4. java微信公众号开发token验证失败的问题及解决办法

    java微信公众号开发token验证失败的问题及解决办法 参考文章: (1)java微信公众号开发token验证失败的问题及解决办法 (2)https://www.cnblogs.com/beardu ...

  5. Java微信公众平台开发--番外篇,对GlobalConstants文件的补充

    转自:http://www.cuiyongzhi.com/post/63.html 之前发过一个[微信开发]系列性的文章,也引来了不少朋友观看和点评交流,可能我在写文章时有所疏忽,对部分文件给出的不是 ...

  6. Java微信公众号开发梳理

    Java微信公众号开发梳理 现在微信公众平台的开发已经越来越普遍,这次开发需要用到微信公众平台.因此做一个简单的记录,也算是给那些没踩过坑的童鞋一些启示吧.我将分几块来简单的描述一下,之后会做详细的说 ...

  7. Java微信公众号开发(一:接入平台,验证token)

    Java微信公众号开发(一:接入平台,验证token) 开发环境: 环境:JDK1.8 框架:springBoot 首先,在我们接入微信公众平台之前,我们需要注册微信公众号的开发者账号,获取开发者ID ...

  8. java 微信自定义菜单开发_微信公众号开发之设置自定义菜单实例代码【java版】...

    本实例是为了实现在管理后台实现微信菜单的添加删除管理. 1.首先我们需要新建一个数据库表用于存放menu菜单项 可包含的字段有id.父类id.name.排序.是否显示.类型(view.click).链 ...

  9. Java微信公众号开发之网页授权获取用户基本信息

    本篇博客讲解的网页授权只需要前端传递一个backUrl(回调地址) 到后台接口,后台接口会完成整个授权流程,无需前端做更多工作: 一. 前言 微信公众号开发,需要用到网页授权获取用户信息,通过OAut ...

最新文章

  1. python mainloop bind_Python3 tkinter基础 Frame bind 捕捉多键同时按
  2. rocksdb写放大_Rocksdb的优劣及应用场景分析
  3. Spring Boot配置文件有提示
  4. django配置templates、static、media和连接mysql数据库
  5. Java dectobin(n)函数_浙大JAVA实验题答案09answer.docx
  6. 《流量的秘密: Google Analytics网站分析与优化技巧(第3版)》一2.2 网站分析中的cookie...
  7. 17. jQuery - css() 方法
  8. 中心极限与大数定理律的关系_【小结】实数域的基本定理
  9. 素数五个为一行的_帕斯卡三角形与素数
  10. li标签中hover的使用及li标签的样式
  11. gtk 程序设计(c语言版) pdf,GTK+程序设计入门
  12. 2013-2014 ACM-ICPC, NEERC, Southern Subregional Contest Problem F. Judging Time Prediction 优先队列...
  13. 三菱Q系列plc11轴运动控制程序
  14. JetPack知识点实战系列十:ExoPlayer进行视频播放的实现
  15. 在图书馆看到自己出版的图书是一种怎样的体验?
  16. 重启linux没有网络配置文件,Linux 网络配置 修改DNS配置文件/etc/resolv.conf后,重启网络,DNS配置丢失...
  17. 机器学习之决策树(Decision Tree)
  18. 计算机组装小白,小白怎么从零开始学组装电脑?
  19. 博客系统(页面设计)
  20. 弹性云服务器的稳定可靠性,弹性云服务器的稳定可靠性

热门文章

  1. java nodejs aes_Java与Node.js利用AES加密解密出相同结果的方法示例
  2. 小白Linux(lubuntu)安装及配置血泪之旅
  3. 计算机管理扩展灰色,为什么c盘扩展卷灰色?win7系统c盘扩展卷灰色如何解决
  4. 案例篇10—css3实现卡通小鸟效果(附源码)
  5. android仿小米运动,GitHub - luciferldy/Bnimation: 模仿即刻 App 点赞与数字跳动效果,模仿小米运动首页转圈圈的烟花效果...
  6. 阿里云 跨域问题处理
  7. 八月25日8点半服务器维修,8月26日服务器例行维护公告
  8. 用Python实现微信自动拉人进群!微商福利!
  9. java应用程序占用高内存_对Java应用程序中的内存问题进行故障排除
  10. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java装修服务网站5ff59