wx-tools WxMessageRouter的使用例子

2023-03-22 17:18 更新

2.5.1 创建菜单栏

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

Menu

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

public class Menu {


    public static void main(String[] args) {
        IService iService = new WxService();
        WxMenu menu = new WxMenu();
        List<WxMenu.WxMenuButton> btnList = new ArrayList<>();


        //飙升功能
        WxMenu.WxMenuButton btn1 = new WxMenu.WxMenuButton();
        btn1.setName("分类");
        List<WxMenu.WxMenuButton> subList = new ArrayList<>();
        WxMenu.WxMenuButton btn1_1 = new WxMenu.WxMenuButton();
        btn1_1.setType(WxConsts.MENU_BUTTON_CLICK);
        btn1_1.setKey(MenuKey.HOT_SONG);
        btn1_1.setName("飙升榜");
        WxMenu.WxMenuButton btn1_2 = new WxMenu.WxMenuButton();
        btn1_2.setType(WxConsts.MENU_BUTTON_CLICK);
        btn1_2.setKey(MenuKey.TOP_500);
        btn1_2.setName("TOP500");
        WxMenu.WxMenuButton btn1_3 = new WxMenu.WxMenuButton();
        btn1_3.setType(WxConsts.MENU_BUTTON_CLICK);
        btn1_3.setKey(MenuKey.NET_HOT_SONG);
        btn1_3.setName("网络红歌");
        WxMenu.WxMenuButton btn1_4 = new WxMenu.WxMenuButton();
        btn1_4.setType(WxConsts.MENU_BUTTON_CLICK);
        btn1_4.setKey(MenuKey.HUAYU_SONG);
        btn1_4.setName("华语新歌");
        WxMenu.WxMenuButton btn1_5 = new WxMenu.WxMenuButton();
        btn1_5.setType(WxConsts.MENU_BUTTON_CLICK);
        btn1_5.setKey(MenuKey.XINAO_SONG);
        btn1_5.setName("洗脑神曲");

        
        WxMenu.WxMenuButton btn2 = new WxMenu.WxMenuButton();
        btn2.setType(WxConsts.MENU_BUTTON_CLICK);
        btn2.setKey(MenuKey.CHANGE_NEWS);
        btn2.setName("换一组");


        WxMenu.WxMenuButton btn3 = new WxMenu.WxMenuButton();
        btn3.setType(WxConsts.MENU_BUTTON_CLICK);
        btn3.setKey(MenuKey.HELP);
        btn3.setName("帮助");


        subList.addAll(Arrays.asList(btn1_1, btn1_2, btn1_3, btn1_4, btn1_5));
        btn1.setSub_button(subList);


        //将三个按钮设置进btnList
        btnList.add(btn1);
        btnList.add(btn2);
        btnList.add(btn3);
        //设置进菜单类
        menu.setButton(btnList);
        //调用API即可
        try {
            //参数1--menu  ,参数2--是否是个性化定制。如果是个性化菜单栏,需要设置MenuRule
            iService.createMenu(menu, false);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }
}

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

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

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

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

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

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

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

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

  • 补充WxController中的Post处理方法:
    
    @PostMapping
    public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        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(); }

}



- HelpDocHandler.java代码如下:


> Handler代码采用单例模式,为了解决消息重试的问题。但由于网络问题导致返回结果慢了。会自动重试,返回多条信息。当然,这种做法不建议你们使用,因为这样写,同一时间仅仅允许一个线程进来处理,并不适合多线程环境。


> 因为这个音乐爬虫项目是做给我女票使用的,用户仅仅只有一个。所以我可以这么做,而你不们作为项目,不可以!!!好了继续~


> 官方关于消息重试的机制[点击这里查看](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(); } }




- 接下来测试一下,点击公众号的帮助按钮,正常返回帮助说明。而点击其他按钮,均无反应。


这样我们就成功利用消息路由和创建第一个规则(Rule)去过滤消息,并处理返回了。 


是不是很简单~2333


现在我们尝试使用wx-tools其他特性,添加更多的功能进去吧~gogogo
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号