JAVA微信公众号开发第2篇之消息处理

简介

当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。

微信服务器在将用户的消息发给公众号的开发者服务器地址(开发者中心处配置)后,微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次,如果在调试中,发现用户无法收到响应的消息,可以检查是否消息处理超时。关于重试的消息排重,有msgid的消息推荐使用msgid排重。事件类型消息推荐使用FromUserName + CreateTime 排重。
以上引用自微信公众平台开发文档

主入口接口

当用户主动向公众号发送消息或者通过菜单与公众号进行交互操作时,微信会通过接入接口的POST方法,与用户后台进行数据交互。

private @Inject BigBigBuHandler handler;
private @Inject BigBigBuInterceptor interceptor;
@RequestMapping(value = "/wxconfig/{wxsystoken}", method = RequestMethod.POST)
    public void wxconfigPOST(@PathVariable("wxsystoken") String wxsystoken, HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
         // 返回消息给微信服务器
        PrintWriter out = response.getWriter();
        // 创建一个路由器
        WxMessageRouter router = new WxMessageRouter();
        try {
            // 微信服务器推送过来的是XML格式。
            WxXmlMessage wx = XmlTransformer.fromXml(WxXmlMessage.class, request.getInputStream());
            System.out.println("消息:\n " + wx.toString());
            // 添加规则;这里的规则是所有消息都交给DemoMatcher处理,交给DemoInterceptor处理,交给DemoHandler处理
            // 注意!!每一个规则,必须由end()或者next()结束。不然不会生效。
            // end()是指消息进入该规则后不再进入其他规则。 而next()是指消息进入了一个规则后,如果满足其他规则也能进入,处理。
            router.rule().async(false).interceptor(interceptor).handler(handler).end();

            // 把消息传递给路由器进行处理
            WxXmlOutMessage xmlOutMsg = router.route(wx);
            if (xmlOutMsg != null)
                out.print(xmlOutMsg.toXml());// 因为是明文,所以不用加密,直接返回给用户。
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            out.close();
        }
    }

以上将信服务器推送过来的是XML格式化为WxXmlMessage对象,通过消息路由交给指定的处理器handler处理,同时处理前通过拦截器进行消息拦截

消息处理器BigBigBuHandler
package com.bigbigbu.handler;

import java.util.Map;

import org.springframework.stereotype.Component;

import com.bigbigbu.model.msg.WxXmlOutMessageExtend;

import me.chanjar.weixin.api.WxConsts;
import me.chanjar.weixin.api.WxMessageHandler;
import me.chanjar.weixin.bean.WxXmlMessage;
import me.chanjar.weixin.bean.WxXmlOutMessage;

/** 
* @ClassName: BigBigBuHandler 
* @Description: TODO 处理器
* @author FANQIBU
* @date 2017年11月24日 上午11:11:28 
*  
*/
@Component
public class BigBigBuHandler implements WxMessageHandler{
    @Override
    public WxXmlOutMessage handle(WxXmlMessage wxMessage, Map<String, Object> context) {
          //必须以build()作为结尾,否则不生效。
        if(wxMessage.getMsgType().equals(WxConsts.XML_MSG_TEXT)){
            return  getText(wxMessage, context);
        }else if(wxMessage.getMsgType().equals(WxConsts.XML_MSG_EVENT)){
             if(wxMessage.getEvent().equals(WxConsts.EVT_SUBSCRIBE)){
                //事件类型.subscribe(订阅事件)
                return  getBySubscribe(wxMessage, context);
             }else if(wxMessage.getEvent().equals(WxConsts.EVT_UNSUBSCRIBE)){
                //事件类型.unsubscribe(取消订阅)
                return getByUnSubscribe(wxMessage, context); 
             }else if(wxMessage.getEvent().equals(WxConsts.EVT_CLICK)){
                //自定义菜单事件
                return getEvtClick(wxMessage, context);
             }
        }
        return null;
    }
    /**   
     * @Title: getEvtClick   
     * @Description: TODO 点击事件处理   
     * @param: @param wxMessage
     * @param: @param context
     * @param: @return      
     * @return: WxXmlOutMessage      
     */  
    private WxXmlOutMessage getEvtClick(WxXmlMessage wxMessage, Map<String, Object> context) {
        // TODO Auto-generated method stub
        return null;
    }
    /**   
     * @Title: getBySubscribe   
     * @Description: TODO 用户订阅事件
     * @param: @param wxMessage
     * @param: @param context
     * @param: @return      
     * @return: WxXmlOutMessage      
     */  
    private WxXmlOutMessage getBySubscribe(WxXmlMessage wxMessage, Map<String, Object> context) {
            StringBuilder builder =new StringBuilder();
        builder.append("欢迎关注蓝海投资理财公众号,这些事情您知道吗? \n");
        builder.append("    1.<a href=\"http://www.baidu.com\">现在来蓝海理财有Iphone领,进来看看吧</a>\n");
        builder.append("    2.<a href=\"http://www.baidu.com\">成为蓝海经纪人不投资,有“工资”</a>\n");
        builder.append("    3.如果已有蓝海帐号,请移步个人中心->老帐户绑定,享受更多服务。");
        return WxXmlOutMessage.TEXT().content(builder.toString()).touser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()).build();
    }
    /**   
     * @Title: getByUnSubscribe   
     * @Description: TODO 取消订阅事件
     * @param: @param wxMessage
     * @param: @param context
     * @param: @return      
     * @return: WxXmlOutMessage      
     */  
    private WxXmlOutMessage getByUnSubscribe(WxXmlMessage wxMessage, Map<String, Object> context) {
        // TODO Auto-generated method stub
        return null;
    }
    /**   
     * @Title: getText   
     * @Description: TODO 文本消息处理  
     * @param: @param wxMessage
     * @param: @param context
     * @param: @return      
     * @return: WxXmlOutMessage      
     */  
    private WxXmlOutMessage getText(WxXmlMessage wxMessage, Map<String, Object> context) {
        if("人工服务".equals(wxMessage.getContent())){
            return WxXmlOutMessageExtend.TEXTForwardKF().content(wxMessage.getContent()).touser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()).buildKf();
        }
        return WxXmlOutMessage.TEXT().content("您好!如有问题,请输入【人工服务】寻求帮助。").touser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()).build();
    }

}

针对不同的消息,服务器可以做消息的响应

消息拦截器BigBigBuInterceptor
package com.bigbigbu.interceptor;

import java.util.Map;

import org.springframework.stereotype.Component;

import me.chanjar.weixin.api.WxMessageInterceptor;
import me.chanjar.weixin.bean.WxXmlMessage;

/**
* @Title: BigBigBuInterceptor
* @Description: 拦截器
* @Company: 卜凡起的博客
* @author    FANQIBU
* @date       2018年1月26日
*/
@Component
public class BigBigBuInterceptor implements WxMessageInterceptor{
    @Override
    public boolean intercept(WxXmlMessage wxMessage, Map<String, Object> context) {
        //拦截所有非TEXT类型的消息,true通行;false拦截
        /*if(WxConsts.XML_MSG_TEXT.equals(wxMessage.getMsgType())){
            return true;
        }*/
        return true;
    }

}

示例演示

这里写图片描述
项目源码

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值