zoukankan      html  css  js  c++  java
  • 公众号开发之wx-tools+springboot应用实战-音乐爬虫推送[JAVA]

    springboot+wx-tools实践!音乐爬虫推送公众号DEMO
    GitHub地址:wx-tools

    最终DEMO源码地址: music_collector

    先理一下大概的开发步骤:
    1. 创建一个Web工程(可以是Servlet/Spring Web/Spring boot)
    2. pom引入wx-tools / 手动引入wx-tools.jar包(可以去github下载自己build)
    3. 编写wx.properties配置文件
    4. 接入微信公众平台,验证服务器地址的有效性
    5. 实现自己的业务逻辑

    简单吗?接下来一起写一个简单的Demo吧

    1. 创建web项目
    注意!本demo使用的是SpringBoot,如果你使用原生servlet,原理是一样的。这里就不再演示。

    使用maven创建,或者在eclipse/IDEA创建web项目。

    如何创建web项目,相信大家都会的了。就不详细介绍了。如果不会,自行度娘。

    基于SpringBoot爬虫项目
    这里我我基于springBoot创建了一个项目名为:music_collector

    music_collector是一个爬虫项目,爬取各大音乐网的排行榜,并且可以支持设置关键字,来查询微信图文推送并推送给用户。(原理是通过搜狗搜索)

    具体创建SpringBoot,这里就不赘述了。百度一下就知道了。

    如果使用maven创建项目,指令如下:
    mvn archetype:generate -DgroupId=wxtools.demo -DartifactId=demo -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeCatalog=local
    1
    2
    注意:此指令创建的web工程版本是2.3的,比较低。可以修改web.xml,变成3.0
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>demo</display-name>
    </web-app>
    1
    2
    3
    4
    引入wx-tools依赖
    maven地址(最新版本可以去中央库查询wx-tools)
    <dependency>
    <groupId>com.soecode.wx-tools</groupId>
    <artifactId>wx-tools</artifactId>
    <version>2.1.4-RELEASE</version>
    </dependency>
    1
    2
    3
    4
    5
    注意:如果需要看源代码的务必手动修改编码。导入后记得修改jar包的编码。window下默认读GBK,而框架本身是UTF-8。
    * 修改方式:在eclipse的工程下,对着jar包右键 –> Properties –> Encoding –> UTF-8

    创建wx.properties配置文件
    搭好项目基本框架后,在src/main/resources下新建wx.properties文件
    #配置如下
    wx.appId=你的appId
    wx.appSecret=你的appSecret
    wx.token=你设置的token
    wx.aesKey=如果选择安全模式,需要填入。如果是明文模式,填空就好了
    wx.mchId=商户ID
    1
    2
    3
    4
    5
    6
    最终项目目录结构如下:

    不要填错了哦!注意大小写。

    2. 验证服务器地址的有效性
    2.3.1 启动web服务
    可以使用SpringBoot启动或者tomcat/jBoss都可以。

    内网映射
    微信开发需要把本地127.0.0.1映射到公网上,微信服务器才可以把消息推送给你的程序。

    映射工具有很多,例如:花生壳、Ngrok等。这里使用了免费版的Ngrok。
    ngrok客户端windows+64版

    使用方法很简单:下载解压,双击打开,输入二级域名即可把本地127.0.0.1映射出去。


    验证一下服务器的有效性
    这时候,wx-tools下的所有api都可以调用了。

    我们验证一下服务器的有效性。

    验证接口官方文档 建议先看官方文档,理解好开发步骤,在继续下去。

    编写WxController对接微信服务器

    @RestController
    @RequestMapping("/wx")
    public class WxController {

    private IService iService = new WxService();

    @GetMapping
    public String check(String signature, String timestamp, String nonce, String echostr) {
    if (iService.checkSignature(signature, timestamp, nonce, echostr)) {
    return echostr;
    }
    return null;
    }

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    开启服务,然后去微信公众平台后台或者测试号后台填写资料验证即可。( 确保wx.properties与微信后台配置一致即可。)

    打开微信配置后台:(这里我是用测试号的,还没有测试号的可以点击这里申请)

    如果发现可以连接,就说明已经与微信服务器对接成功(验证成功)。接下来任何对你的公众号操作,微信服务器都会转发消息给你的服务器(你的程序)。

    3. 接收微信服务器发来的消息
    当你验证服务器有消息成功后,微信服务器就会把你的公众号任何事件和消息,以post请求推送到你验证的那个url地址上。所以我们现在需要做的就是写一个Post接收方法,来接收发来的消息~

    完善WxController,添加Post接收方法
    @RestController
    @RequestMapping("/wx")
    public class WxController {

    private IService iService = new WxService();

    @GetMapping
    public String check(String signature, String timestamp, String nonce, String echostr) {
    if (iService.checkSignature(signature, timestamp, nonce, echostr)) {
    return echostr;
    }
    return null;
    }

    @PostMapping
    public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");
    PrintWriter out = response.getWriter();

    try {
    // 微信服务器推送过来的是XML格式。
    WxXmlMessage wx = XStreamTransformer.fromXml(WxXmlMessage.class, request.getInputStream());
    System.out.println("消息: " + wx.toString());
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    out.close();
    }

    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    可以看到,我把微信服务器发来的消息(request)的输入流扔给了XStreamTransformer来帮忙解析XML,并返回WxXmlMessage类。
    - WxXmlMessage类是统一消息的载体。所有消息包括事件推送都包含在这个类当中。

    尝试与公众号交互,观察控制台
    这时候,我们可以尝试向公众号发送一句:“Hello”。我们看一下结果。

    wx-tools自动把发来的消息封装成一个类,方便处理。

    我们再试试接收并解析事件(Event)推送,例如:新用户关注事件推送。

    我用另一个微信号关注了一波我的测试号,观察控制台:

    好了,至此。你已经成功一大半了。为什么呢!因为剩下的就是拿着这个消息(Message)去各种处理,最后返回给用户想要的东西即可~

    下篇会讲一些路由器的使用方式,请移步下篇!嘻嘻

    4. WxMessageRouter的使用例子
    创建菜单栏
    假设一下,我现在想把公众号的菜单栏设置成这样的:

    我们可以写一个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();
    }
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    接下来直接运行就行了,你就会看到你的公众号菜单栏的变化。
    菜单栏的参数设置,请参考官方文档 - 菜单栏的创建, 菜单栏的按钮有分很多种类型(type),例如click,view等。详情建议先看官方文档。

    创建消息路由并设置第一个规则(Rule)
    假设需求如下: 我只接收菜单栏类型为:Click,且Key为MenuKey.HELP的消息,其他一律放弃不接收。

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

    if("CLICK".equals(message.event) && MenuKey.HELP.equals(message.eventKey)){
    doSomething();
    }
    1
    2
    3
    这样的写法会随着需求增多,而越来越庞大臃肿。

    而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("消息: " + 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
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    HelpDocHandler.java代码如下:
    Handler代码采用单例模式,为了解决消息重试的问题。但由于网络问题导致返回结果慢了。会自动重试,返回多条信息。当然,这种做法不建议你们使用,因为这样写,同一时间仅仅允许一个线程进来处理,并不适合多线程环境。

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

    官方关于消息重试的机制点击这里查看。

    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
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    接下来测试一下,点击公众号的帮助按钮,正常返回帮助说明。而点击其他按钮,均无反应。
    这样我们就成功利用消息路由和创建第一个规则(Rule)去过滤消息,并处理返回了。

    是不是很简单~2333

    现在我们尝试使用wx-tools其他特性,添加更多的功能进去吧~gogogo

    完成菜单栏剩余功能
    按钮[分类-飙升榜]
    需求:当用户点击此按钮,后台爬虫帮我爬当天酷狗飙升榜的列表下来,并返回。 酷狗飙升榜在这。

    爬虫技术不是本文档的主要内容,所以在此就不细讲如何爬下数据。有兴趣的同学可以阅读下源代码。(原理很简单,仅仅使用HttpClient+Jsoup)
    添加RankHandler.java
    此handler专门处理爬虫分类Event事件。

    RankHandler.java:(负责处理消息部分)

    public class RankHandler implements WxMessageHandler {
    private static RankHandler instance = null;
    private boolean isRun = false;
    private RankHandler() {}

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

    @Override
    public WxXmlOutMessage handle(WxXmlMessage wxMessage, Map<String, Object> context, IService iService)
    throws WxErrorException {
    StringBuilder result = new StringBuilder();
    if (!getIsRun()) {
    setRun(true);
    try {
    result = execute(wxMessage);
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    setRun(false);
    }
    } else {
    result.append(ResponseConst.DUPLICATE_REQUEST);
    }
    return WxXmlOutMessage.TEXT().content(result.toString()).toUser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()).build();
    }

    private StringBuilder execute(WxXmlMessage wxMessage) throws Exception{
    StringBuilder stringBuilder = new StringBuilder();
    try {
    switch (wxMessage.getEventKey()) {
    case MenuKey.HOT_SONG:
    collectSongRank(stringBuilder, UrlConst.HOT_RANK_URL);
    break;
    default:
    stringBuilder.append("暂时无此分类噢!");
    break;
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    return stringBuilder;
    }

    private void collectSongRank(StringBuilder stringBuilder, String url) throws IOException {
    RankCollector collector = new RankCollector();
    Rank rank = collector.collect(url);
    stringBuilder.append("uD83DuDD25" + rank.getScope() + "[" + rank.getUpdateTime() + "] ");
    for (HotSinger hotSinger : rank.getHotSingerList()) {
    stringBuilder.append(hotSinger.getName() + "-" + hotSinger.getHotSong() + " ");
    }
    }

    private synchronized boolean getIsRun() {
    return isRun;
    }

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

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    RankCollector.java: (爬虫部分)

    public class RankCollector {

    public Rank collect(String url) throws IOException {
    return getRank(url);
    }

    private Rank getRank(String rankUrl) throws IOException {
    Rank rank = new Rank();
    String body = HttpClientUtil.get(rankUrl);
    Document doc = Jsoup.parse(body);
    rank.setScope(doc.select("a[class=current]").attr("title"));
    rank.setUpdateTime(doc.select("span[class=rank_update]").text());
    List<Element> aElements = doc.select("a[data-active=playDwn]");
    for(int i = 0; i < aElements.size(); i++){
    String[] splitArray = aElements.get(i).text().split("-");
    String name = splitArray[0].toString().trim();
    String song = splitArray[1].toString().trim();
    rank.getHotSingerList().add(new HotSinger(doc.select("a[class=current]").attr("title"), name, song));
    }
    return rank;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    添加新的规则(Rule)
    修改新增WxController的路由规则:

    router.rule().event(WxConsts.EVT_CLICK).eventKey(MenuKey.HELP).handler(HelpDocHandler.getInstance()).next()
    .rule().eventKey(MenuKey.HOT_SONG).handler(RankHandler.getInstance()).end();
    1
    2
    这里解释一下:next()和end()的意思。
    next() 表示消息经过第一个规则(Rule)之后,允许继续匹配下面的规则,代表着同一个消息有可能被多个Handler处理。
    end() 表示规则的结束。当消息满足某条规则时遇到end(),不会再往下匹配规则,就此结束。
    重新运行,并测试


    当天的飙升榜就这样返回回来了~很激动有木有!

    好了同一原理实现其他4个排行榜按钮的功能,这里就不展示了。详情可以查看demo源码。
    5. WxMessageMatcher接口实现例子
    WxMessageMatcher(消息匹配器)接口用于一些简单的匹配,可以自定义匹配逻辑,如格式验证。匹配成功则继续往下执行,否则不允许通过。

    需求:我想当用户发送文本消息:“我是谁”时,后台获取该用户的微信用户信息(昵称)并返回。

    创建WhoAmIMatcher.java
    用于匹配符合”我是谁“的消息。

    public class WhoAmIMatcher implements WxMessageMatcher{

    @Override
    public boolean match(WxXmlMessage message) {
    if(StringUtils.isNotEmpty(message.getContent())){
    if(message.getContent().equals("我是谁")){
    return true;
    }
    }
    return false;
    }

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    创建WhoAmIHandler.java
    用于处理当匹配到“我是谁”的消息。

    修改路由规则:(这时候已经把所有的爬虫都写完啦!所以路由规则这么多!)
    router.rule().msgType(WxConsts.XML_MSG_TEXT).matcher(new WhoAmIMatcher()).handler(new WhoAmIHandler()).end()
    .rule().event(WxConsts.EVT_CLICK).eventKey(MenuKey.HELP).handler(HelpDocHandler.getInstance()).next()
    .rule().eventKey(MenuKey.HOT_SONG).handler(RankHandler.getInstance()).next()
    .rule().eventKey(MenuKey.TOP_500).handler(RankHandler.getInstance()).next()
    .rule().eventKey(MenuKey.NET_HOT_SONG).handler(RankHandler.getInstance()).next()
    .rule().eventKey(MenuKey.HUAYU_SONG).handler(RankHandler.getInstance()).next()
    .rule().eventKey(MenuKey.XINAO_SONG).handler(RankHandler.getInstance()).end();
    1
    2
    3
    4
    5
    6
    7
    8
    运行,并测试
    如图所示,输入”我是谁“的时候,返回了我微信的昵称。

    小小总结一下
    至此,我们已经尝试使用了路由器Router,规则Rule,匹配器Matcher,处理器Handler。

    还有使用了IServer统一接口调用去获取用户信息。

    IServer 接口是集成所有wx-tools已经实现的微信接口,统一调用入口。它的实现是WxService.java。想看实现源码的可以戳:这里

    6.WxMessageInterceptor接口实现例子
    WxMessageInterceptor(拦截器)功能与Matcher相同,用于过滤拦截,但是与Matcher最大的不同就是,它支持更复杂的业务处理,因为它携带了IService和上下文context,可以利用这两个参数进行业务处理。

    IService : 统一接口调用入口。
    context :上下文,可以向handler传递参数。
    WxMessageInterceptor拦截器接口,可以处理更加复杂的验证。例如身份验证,时效校验等等。

    由于我的音乐爬虫项目并没有涉及到这么深的处理,所以这里只给出一个DemoInterceptor看看。

    假设需求:只有用户关注公众号时长大于3天才能参与活动。

    创建DemoInterceptor.java 实现 WxMessageInterceptor接口
    /**
    * Demo 拦截器,可以通过WxService做更加复杂的拦截,例如身份验证,权限验证等操作。
    * @author antgan
    *
    */
    public class DemoInterceptor implements WxMessageInterceptor{

    public boolean intercept(WxXmlMessage wxMessage, Map context, IService wxService) throws WxErrorException {
    //可以使用wxService的微信API方法
    //可以在Handler和Interceptor传递消息,使用context上下文
    //可以实现自己的业务逻辑
    //这里就不编写验证关注三天以上的用户了
    if(/*用户关注时长大于3天*/){
    return true;
    }
    return false;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    接下来你们都知道的,修改路由器规则,添加interceptor。
    例如:

    router.rule().matcher(new DemoMatcher()).interceptor(new DemoInterceptor()).handler(new DemoMessageHandler()).end();
    1
    2
    搞定。接下来交给wx-tools去做吧~
    简单吧!

    7. 关于WxMessageRouter及Rule的详解
    WxMessageRouter消息路由器,不知道你们理解了多少,接下来还是详细讲解一下需要注意的细节。

    提到这个路由器,就要说说另一个东西:WxMessageRouterRule。简称规则(Rule)。

    定义规则,用于对来自微信服务器的消息进行过滤和筛选,只针对有效消息进行处理,提高服务器处理效率。

    通过链式配置路由规则(Rule),根据规则把来自微信的消息交给handler处理。

    注意:
    配置路由规则时尽量按照从细到粗的原则,否则可能消息可能会被提前处理
    默认情况下消息只会被处理一次,除非使用 {WxMessageRouterRule的next()方法}
    规则的结束必须用WxMessageRouterRule的end()方法或者WxMessageRouterRule的next()方法,否则不会生效。
    使用方法:
    //初始化一个路由器,把wxService传入。
    WxMessageRouter router = new WxMessageRouter(wxService);
    //新建路由规则,通过rule()方法创建新的规则,然后链式填写过滤条件。MSG_TYPE等参数填入WxConst中的常量,这里不作展示,可以查看WxConst代码或官方文档,有注释。
    router.rule().msgType("MSG_TYPE").event("EVENT").eventKey("EVENT_KEY").content("CONTENT").matcher(matcher).interceptor(interceptor, ...).handler(handler, ...).end()
    .rule().msgType("MSG_TYPE")...//另外一个匹配规则.end();
    // 将WxXmlMessage交给消息路由器,处理后得到结果。
    WxXmlOutMessage xmlOutMsg = router.route(wxXmlMessage);
    1
    2
    3
    4
    5
    6
    7
    关于路由规则条件
    对于一条消息(WxXMLMessage)允许多个规则(Rule)去进行过滤和处理。用next()方法去连接两个规则。但是最后必须是以end()方法结束。
    每条规则可以允许多个拦截器(Interceptor),多个处理器(Handler)处理。返回最后一个Handler处理的结果。
    路由规则还提供正则表达式过滤,对于简单的过滤需求,如只接受数字消息。不想繁琐的建立Matcher匹配器。可以如下写法。
    //正则表达式:^[0-9]*$只接受数字消息,其他消息过滤。
    router.rule().rContent("^[0-9]*$").handler(new DemoHandler()).end();
    1
    2
    去除多余消息,高效处理争对性消息,真是好用又简单。

    小小总结一下
    至此,如果你跟着做,并且都成功了话。你已经入门了wx-tools了。以后无非就是根据用户需求添加路由规则,并添加处理器去处理,入门教程就到此结束了。

    DEMO的源码下载地址: music_collector

    其实DEMO里还有关键字搜索并推送图文消息给用户的功能. 文档里没演示出来.有兴趣的同学可以查阅源代码.

    最终效果图~可以是这样

     --------------------- 

    作者:antgan
    来源:CSDN
    原文:https://blog.csdn.net/antgan/article/details/80288061
    版权声明:本文为博主原创文章,转载请附上博文链接!

    https://www.cnblogs.com/lanxiaoke/p/6426223.html

  • 相关阅读:
    前端与算法 leetcode 344. 反转字符串
    JavaScript闭包使用姿势指南
    前端与算法 leetcode 48. 旋转图像
    前端与算法 leetcode 36. 有效的数独
    前端与算法 leetcode 1. 两数之和
    前端与算法 leetcode 283. 移动零
    前端与编译原理 用js去运行js代码 js2run
    前端与算法 leetcode 66. 加一
    前端与算法 leetcode 350. 两个数组的交集 II
    前端与算法 leetcode 26. 删除排序数组中的重复项
  • 原文地址:https://www.cnblogs.com/softidea/p/10370574.html
Copyright © 2011-2022 走看看