wx-tools WxMessageRouter的使用例子

2023-03-22 17:18 更新

2.5.1 创建菜单栏

假设一下,我现在想把公众号的菜单栏设置成这样的:

Menu

我们可以写一个Main方法,来更改公众号的菜单栏,代码如下:

  1. public class Menu {
  2. public static void main(String[] args) {
  3. IService iService = new WxService();
  4. WxMenu menu = new WxMenu();
  5. List<WxMenu.WxMenuButton> btnList = new ArrayList<>();
  6. //飙升功能
  7. WxMenu.WxMenuButton btn1 = new WxMenu.WxMenuButton();
  8. btn1.setName("分类");
  9. List<WxMenu.WxMenuButton> subList = new ArrayList<>();
  10. WxMenu.WxMenuButton btn1_1 = new WxMenu.WxMenuButton();
  11. btn1_1.setType(WxConsts.MENU_BUTTON_CLICK);
  12. btn1_1.setKey(MenuKey.HOT_SONG);
  13. btn1_1.setName("飙升榜");
  14. WxMenu.WxMenuButton btn1_2 = new WxMenu.WxMenuButton();
  15. btn1_2.setType(WxConsts.MENU_BUTTON_CLICK);
  16. btn1_2.setKey(MenuKey.TOP_500);
  17. btn1_2.setName("TOP500");
  18. WxMenu.WxMenuButton btn1_3 = new WxMenu.WxMenuButton();
  19. btn1_3.setType(WxConsts.MENU_BUTTON_CLICK);
  20. btn1_3.setKey(MenuKey.NET_HOT_SONG);
  21. btn1_3.setName("网络红歌");
  22. WxMenu.WxMenuButton btn1_4 = new WxMenu.WxMenuButton();
  23. btn1_4.setType(WxConsts.MENU_BUTTON_CLICK);
  24. btn1_4.setKey(MenuKey.HUAYU_SONG);
  25. btn1_4.setName("华语新歌");
  26. WxMenu.WxMenuButton btn1_5 = new WxMenu.WxMenuButton();
  27. btn1_5.setType(WxConsts.MENU_BUTTON_CLICK);
  28. btn1_5.setKey(MenuKey.XINAO_SONG);
  29. btn1_5.setName("洗脑神曲");
  30. WxMenu.WxMenuButton btn2 = new WxMenu.WxMenuButton();
  31. btn2.setType(WxConsts.MENU_BUTTON_CLICK);
  32. btn2.setKey(MenuKey.CHANGE_NEWS);
  33. btn2.setName("换一组");
  34. WxMenu.WxMenuButton btn3 = new WxMenu.WxMenuButton();
  35. btn3.setType(WxConsts.MENU_BUTTON_CLICK);
  36. btn3.setKey(MenuKey.HELP);
  37. btn3.setName("帮助");
  38. subList.addAll(Arrays.asList(btn1_1, btn1_2, btn1_3, btn1_4, btn1_5));
  39. btn1.setSub_button(subList);
  40. //将三个按钮设置进btnList
  41. btnList.add(btn1);
  42. btnList.add(btn2);
  43. btnList.add(btn3);
  44. //设置进菜单类
  45. menu.setButton(btnList);
  46. //调用API即可
  47. try {
  48. //参数1--menu ,参数2--是否是个性化定制。如果是个性化菜单栏,需要设置MenuRule
  49. iService.createMenu(menu, false);
  50. } catch (WxErrorException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. }

  • 接下来直接运行就行了,你就会看到你的公众号菜单栏的变化。

菜单栏的参数设置,请参考官方文档 - 菜单栏的创建, 菜单栏的按钮有分很多种类型(type),例如click,view等。详情建议先看官方文档。

2.5.2 创建消息路由并设置第一个规则(Rule)

假设需求如下: 我只接收菜单栏类型为:Click,且Key为MenuKey.HELP的消息,其他一律放弃不接收。

正常来说,常规写法应该是加一个if判断,例如:

  1. if("CLICK".equals(message.event) && MenuKey.HELP.equals(message.eventKey)){
  2. doSomething();
  3. }

这样的写法会随着需求增多,而越来越庞大臃肿。

而wx-tools使用消息路由的方式去过滤处理消息,写法如下:

  • 补充WxController中的Post处理方法:
    1. @PostMapping
    2. public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
    3. request.setCharacterEncoding("UTF-8");
    4. response.setCharacterEncoding("UTF-8");
    5. PrintWriter out = response.getWriter();

// 创建一个路由器 WxMessageRouter router = new WxMessageRouter(iService); try { // 微信服务器推送过来的是XML格式。 WxXmlMessage wx = XStreamTransformer.fromXml(WxXmlMessage.class, request.getInputStream()); System.out.println("消息:\n " + wx.toString()); router.rule().event(WxConsts.EVT_CLICK).eventKey(MenuKey.HELP).handler(HelpDocHandler.getInstance()).end(); // 把消息传递给路由器进行处理 WxXmlOutMessage xmlOutMsg = router.route(wx); if (xmlOutMsg != null) // 因为是明文,所以不用加密,直接返回给用户 out.print(xmlOutMsg.toXml());。

} catch (Exception e) { e.printStackTrace(); } finally { out.close(); }

}

  1. - HelpDocHandler.java代码如下:
  2. > Handler代码采用单例模式,为了解决消息重试的问题。但由于网络问题导致返回结果慢了。会自动重试,返回多条信息。当然,这种做法不建议你们使用,因为这样写,同一时间仅仅允许一个线程进来处理,并不适合多线程环境。
  3. > 因为这个音乐爬虫项目是做给我女票使用的,用户仅仅只有一个。所以我可以这么做,而你不们作为项目,不可以!!!好了继续~
  4. > 官方关于消息重试的机制[点击这里查看](https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140453)。

public class HelpDocHandler implements WxMessageHandler {

private static HelpDocHandler instance = null;

private boolean isRun = false;

private HelpDocHandler(){}

public static synchronized HelpDocHandler getInstance(){ if (instance == null) { instance = new HelpDocHandler(); } return instance; }

private synchronized boolean getIsRun() { return isRun; }

private synchronized void setRun(boolean run) { isRun = run; }

@Override public WxXmlOutMessage handle(WxXmlMessage wxMessage, Map<String, Object> context, IService iService) throws WxErrorException { WxXmlOutMessage response = null; if (!getIsRun()) { setRun(true); response = execute(wxMessage); setRun(false); } return response; }

private WxXmlOutMessage execute(WxXmlMessage wxMessage) { return WxXmlOutMessage.TEXT().content(ResponseConst.HELP).toUser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()).build(); } }

  1. - 接下来测试一下,点击公众号的帮助按钮,正常返回帮助说明。而点击其他按钮,均无反应。
  2. 这样我们就成功利用消息路由和创建第一个规则(Rule)去过滤消息,并处理返回了。
  3. 是不是很简单~2333
  4. 现在我们尝试使用wx-tools其他特性,添加更多的功能进去吧~gogogo
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号