一、前言

  1. 微信公众号开发 (1) 微信接入认证成为开发者
  2. 微信公众号开发 (2) 消息处理
本文将实现
  1. 根据AppIDAppSecret获取access_token
  2. 自定义菜单(创建菜单查询菜单删除菜单
微信文档中提示的一些注意点:
  1. access_token存储至少要保留512字符空间。
  2. access_token的有效期2小时,需定时刷新,重复获取将导致上次获取的access_token失效
  3. 自定义菜单最多3个一级菜单,每一级菜单最多5个二级菜单
  4. 一级菜单最多4个汉字二级菜单最多7个汉字
  5. 菜单刷新策略:5分钟之后更新菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果

二、RestTemplate配置 (用于远程调用微信http接口方法)

RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

@Configuration
public class RestTemplateConfig {@Beanpublic RestTemplate restTemplate() {RestTemplate restTemplate = new RestTemplate();// 解决post请求中文乱码问题restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));return restTemplate;}}

三、微信接口调用说明

  1. 获取access_token接口 : 【GET请求】 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
  2. 查询菜单接口 : 【GET请求】 https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
  3. 删除菜单接口 : 【GET请求】 https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
  4. 创建菜单接口 : 【POST请求】 https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
封装微信接口所需变量
public class Constants {/*** TODO 填写自己的 `appID` 和 `appsecret`*/public static final String APP_ID = "xxx";public static final String APP_SECRET = "xxx";/*** 通过 `GET请求方式` 获取 `access_token`*/public static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";/*** TODO 只做临时方便测试使用*/public static final String ACCESS_TOKEN = "xxx";/*** 查询菜单接口 - GET请求*/public static final String GET_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";/*** 删除菜单接口 - GET请求 (注意,在个性化菜单时,调用此接口会删除默认菜单及全部个性化菜单)*/public static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";/*** 创建菜单接口 - POST请求*/public static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";}

四、根据AppIDAppSecret获取access_token

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口(下面的创建菜单查询菜单删除菜单等)时都需使用access_token!

这里可查看微信文档获取access_token方式

① 封装响应结果AccessTokenVO
@Data
@ApiModel(description = "access_token: 公众号的全局唯一接口调用凭据")
public class AccessTokenVO {@ApiModelProperty(value = "获取到的凭证")private String access_token;@ApiModelProperty(value = "凭证有效时间,单位:秒(微信目前暂7200秒,即2小时,过期后需再次获取)")private int expires_in;}
② 服务类
public interface IWeixinService {/*** 根据AppID和AppSecret获取access_token** @param appId:* @param appSecret:* @return: com.zhengqing.demo.modules.weixin.model.AccessTokenVO*/AccessTokenVO getAccessToken(String appId, String appSecret);}
③ 服务实现类
@Slf4j
@Service
public class WeixinServiceImpl implements IWeixinService {@Autowiredprivate RestTemplate restTemplate;@Overridepublic AccessTokenVO getAccessToken(String appId, String appSecret) {AccessTokenVO accessTokenVO = restTemplate.getForObject(Constants.GET_ACCESS_TOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecret), AccessTokenVO.class);return accessTokenVO;}}

五、自定义菜单处理

clickview请求示例

{"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"}]}]}

1、封装菜单数据

温馨小提示:这里封装数据建议多看下微信文档中给出的数据,不然可能会对最后组装菜单树数据创建菜单的时候感到迷惑 ~

① 菜单类型枚举类
public enum MenuType {// 点击式菜单CLICK("click"),// 链接式菜单VIEW("view");
}
② 菜单 - 基类
@Data
@ApiModel(description = "菜单 - 基类")
public class Button {@ApiModelProperty(value = "菜单标题,不超过16个字节,子菜单不超过60个字节")private String name;}
③ 点击式菜单
@Data
@ApiModel(description = "用户点击菜单可接收消息推送")
public class ClickButton extends Button {@ApiModelProperty(value = "菜单的响应动作类型,view表示网页类型,click表示点击类型,miniprogram表示小程序类型")private String type = MenuType.CLICK.getType();@ApiModelProperty(value = "菜单KEY值,用于消息接口推送,不超过128字节")private String key;}
④ 链接式菜单
@Data
@ApiModel(description = "用户点击菜单可打开链接")
public class ViewButton extends Button {@ApiModelProperty(value = "菜单的响应动作类型,view表示网页类型,click表示点击类型,miniprogram表示小程序类型")private String type = MenuType.VIEW.getType();@ApiModelProperty(value = "(view、miniprogram类型必须) 网页 链接,用户点击菜单可打开链接,不超过1024字节。 type为miniprogram时,不支持小程序的老版本客户端将打开本url")private String url;}
⑤ 含二级菜单的一级菜单
@Data
@ApiModel(description = "含二级菜单的一级菜单")
public class ComplexButton extends Button {@ApiModelProperty(value = "二级菜单数组,个数应为1~5个")private Button[] sub_button;}
⑥ 最外层的菜单树
@Data
@ApiModel(description = "菜单树")
public class Menu {@ApiModelProperty(value = "一级菜单数组,个数应为1~3个")private Button[] button;}

2、服务类

public interface IMenuService {/*** 查询菜单** @param accessToken:访问凭据* @return: java.lang.Object*/Object getMenu(String accessToken);/*** 删除菜单** @param accessToken:访问凭据* @return: com.zhengqing.demo.modules.weixin.model.WeixinResponseResult*/WeixinResponseResult deleteMenu(String accessToken);/*** 创建菜单** @param menu        : 创建的菜单数据* @param accessToken : 访问凭据* @return: com.zhengqing.demo.modules.weixin.model.WeixinResponseResult*/WeixinResponseResult createMenu(Menu menu, String accessToken);}

3、服务实现类

@Slf4j
@Service
public class MenuServiceImpl implements IMenuService {@Autowiredprivate RestTemplate restTemplate;@Overridepublic Object getMenu(String accessToken) {Object menu = restTemplate.getForObject(Constants.GET_MENU_URL.replace("ACCESS_TOKEN", accessToken), Object.class);return menu;}@Overridepublic WeixinResponseResult deleteMenu(String accessToken) {WeixinResponseResult result = restTemplate.getForObject(Constants.DELETE_MENU_URL.replace("ACCESS_TOKEN", accessToken), WeixinResponseResult.class);return result;}@Overridepublic WeixinResponseResult createMenu(Menu menu, String accessToken) {// 将菜单对象转换成json字符串String jsonMenu = JSON.toJSONString(menu);WeixinResponseResult result = restTemplate.postForObject(Constants.CREATE_MENU_URL.replace("ACCESS_TOKEN", accessToken), jsonMenu, WeixinResponseResult.class);return result;}}

六、测试

1、获取access_token
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class WeixinTest {@Autowiredprivate IWeixinService weixinService;@Test // 获取 `access_token`public void getAccessToken() throws Exception {AccessTokenVO accessTokenVO = weixinService.getAccessToken(Constants.APP_ID, Constants.APP_SECRET);log.info("======================================== \n" + accessTokenVO.getAccess_token());}}
2、创建自定义菜单查询菜单删除菜单

注:这里小编将获取到的access_token 写死到常量 Constants.ACCESS_TOKEN 中做测试,实际项目中可将access_token保存到缓存中,每隔快到2个小时的时候去重新获取一次刷新缓存数据 ~

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class MenuTest {@Autowiredprivate IMenuService menuService;@Test // 查询菜单public void getMenu() {Object menu = menuService.getMenu(Constants.ACCESS_TOKEN);log.info("======================================== \n" + JSON.toJSONString(menu));}@Test // 删除菜单public void deleteMenu() {WeixinResponseResult result = menuService.deleteMenu(Constants.ACCESS_TOKEN);log.info("======================================== \n" + result);}@Test // 创建菜单public void createMenu() {WeixinResponseResult result = menuService.createMenu(createMenuTree(), Constants.ACCESS_TOKEN);log.info("======================================== \n" + result);}/*** 菜单数据*/private Menu createMenuTree() {// 链接式菜单ViewButton btn11 = new ViewButton();btn11.setName("CSDN");btn11.setUrl("https://zhengqing.blog.csdn.net/");ViewButton btn12 = new ViewButton();btn12.setName("个人博客");btn12.setUrl("http://zhengqingya.gitee.io/blog/");// 点击式菜单ClickButton mainBtn2 = new ClickButton();mainBtn2.setName("点我吖");mainBtn2.setKey("hello");ViewButton btn31 = new ViewButton();btn31.setName("码云");btn31.setUrl("https://gitee.com/zhengqingya/projects");ViewButton btn32 = new ViewButton();btn32.setName("GitHub");btn32.setUrl("https://github.com/zhengqingya?tab=repositories");// 含二级菜单的一级菜单ComplexButton mainBtn1 = new ComplexButton();mainBtn1.setName("博客");mainBtn1.setSub_button(new ViewButton[]{btn11, btn12});ComplexButton mainBtn3 = new ComplexButton();mainBtn3.setName("仓库");mainBtn3.setSub_button(new ViewButton[]{btn31, btn32});Menu menu = new Menu();menu.setButton(new Button[]{mainBtn1, mainBtn2, mainBtn3});return menu;}}

最终自定义的菜单

本文案例demo源码

https://gitee.com/zhengqingya/java-workspace

微信公众号开发 (3) 菜单处理相关推荐

  1. java自定义菜单跳转页面_微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解...

    微信公众号开发 自定义菜单 请先读完本文再进行配置开发 请先前往微信平台开发者文档阅读"网页授权获取用户基本信息"的接口说明 在微信公众账号开发中,往往有定义一个菜单,然后用户点击 ...

  2. 微信公众号开发--自定义菜单跳转页面并获取用户信息(续)

    之前写过一篇微信公众号开发–自定义菜单跳转页面并获取用户信息 由于当时是刚学习微信公众号开发当时的思路虽然可行,不过不是最好的,最近也用到了需要获取用户信息的地方,再次整理一下. 流程 注意点 ### ...

  3. 公众号如何跳转到页面php,图文详解微信公众号开发自定义菜单跳转页面并获取用户信息实例...

    这篇文章主要介绍了微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解的相关资料,需要的朋友可以参考下 微信公众号开发 自定义菜单 请先读完本文再进行配置开发 请先前往微信平台开发者文档阅读&qu ...

  4. 微信公众号开发 - 创建菜单

    微信公众号开发文章目录 1.微信公众号开发 - 环境搭建 2.微信公众号开发 - 配置表设计以及接入公众号接口开发 3.微信公众号开发 - token获取(保证同一时间段内只请求一次) 4.微信公众号 ...

  5. 微信公众号开发---自定义菜单的创建及菜单事件响应(java)

    微信5.0发布 2013年8月5日,伴随着微信5.0 iPhone版的发布,公众平台也进行了重要的更新,主要包括: 1)运营主体为组织,可选择成为服务号或者订阅号: 2)服务号可以申请自定义菜单: 3 ...

  6. 微信公众号开发 - 配置表设计以及接入公众号接口开发

    微信公众号开发文章目录 1.微信公众号开发 - 环境搭建 2.微信公众号开发 - 配置表设计以及接入公众号接口开发 3.微信公众号开发 - token获取(保证同一时间段内只请求一次) 4.微信公众号 ...

  7. 微信公众号开发 - 事件处理和回复消息

    微信公众号开发文章目录 1.微信公众号开发 - 环境搭建 2.微信公众号开发 - 配置表设计以及接入公众号接口开发 3.微信公众号开发 - token获取(保证同一时间段内只请求一次) 4.微信公众号 ...

  8. 微信公众号开发 - token获取(保证同一时间段内只请求一次)

    微信公众号开发文章目录 1.微信公众号开发 - 环境搭建 2.微信公众号开发 - 配置表设计以及接入公众号接口开发 3.微信公众号开发 - token获取(保证同一时间段内只请求一次) 4.微信公众号 ...

  9. 微信公众号开发 - 发送Emoji表情

    微信公众号开发文章目录 1.微信公众号开发 - 环境搭建 2.微信公众号开发 - 配置表设计以及接入公众号接口开发 3.微信公众号开发 - token获取(保证同一时间段内只请求一次) 4.微信公众号 ...

最新文章

  1. C#实现HttpPost提交文件
  2. oracle minus 与sqlserver except
  3. C语言复习篇之数组与指针
  4. ARC082F - Sandglass(思维)
  5. 刚刚教育部发声:老师性骚扰学生 零容忍!“害群之马”将被严惩
  6. android开发 问卷调查案例_Android开发Handler的简单使用——随机点名案例
  7. 撤销commit且未push操作的git命令
  8. 如何使用:after伪元素和:before伪元素
  9. python设计选择题代码_《Python程序的设计》试题库完整
  10. lib库知识全面讲解(.lib、.dll)
  11. osgEarth示例分析——osgearth_manip
  12. PAKDD 2019 都有哪些重要看点?看这篇文章就够了!
  13. Gank教学贴:Gank是一门艺术 不是固定的套路
  14. 【Android】对话框AlertDialog的使用(一)
  15. 51单片机---一起来学习DS1302可调时钟(stc89c52芯片)
  16. C语言解决exe程序闪退最简单的方法。
  17. Git 补丁patch
  18. srm供应商关系管理系统
  19. android 摄像头感光,为何苹果手机摄像头像素那么低 拍出来的效果却比安卓机好?...
  20. 物联网APP:使用android studio实现阿里云物联网平台数字签名(Signature)(附源代码)

热门文章

  1. 消灭该死的重复 下(2) break 跳出
  2. web前端css伪元素使用阿里iconfont中Unicode编码
  3. 脉冲消融(PFA)中使用心电门控的作用
  4. 如何管理保护布线系统,从四个方面来说明
  5. 请问如何判断一段文本中是否含有词典中的词语,并且把它们统计出来呀,有无大神赐教呀!!!
  6. 暴雪魔兽世界用安全令牌送双头犬宠物
  7. 基于java的springboot在线购物商城系统毕业设计springboot开题报告
  8. 卓越的教练是如何训练高手的
  9. 数学建模常用的十大算法
  10. JavaScript奇淫技巧(一)