使用binarywang的微信SDK,开源SDK,公司连不上GitHub,放个gitee的地址吧 https://gitee.com/binary
定义一个管理类,实现ApplicationRunner,项目启动后执行run方法,将微信的相关配置进行初始化。这时候会将微信消息处理的handler初始化到消息处理路由中。SDK中关于微信消息路由器的描述如下:
微信消息路由器,通过代码化的配置,把来自微信的消息交给handler处理
说明:
1. 配置路由规则时要按照从细到粗的原则,否则消息可能会被提前处理 2. 默认情况下消息只会被处理一次,除非使用 WxMpMessageRouterRule.next() 3. 规则的结束必须用WxMpMessageRouterRule.end()或者WxMpMessageRouterRule.next(),否则不会生效
路由器中可以放置对应的handler和拦截器进行消息的处理,拦截器在项目中没有实际应用,这里不再赘述。
微信消息拦截器,可以用来做验证
public interface WxMpMessageInterceptor {
/**
* 拦截微信消息
*
* @param wxMessage
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param wxMpService
* @param sessionManager
* @return true代表OK,false代表不OK
*/
boolean intercept(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException;
}
WxMpMessageHandler,SDK中定义的处理微信推送消息的处理器接口。项目中定义一个抽象类,实现WxMpMessageHandler接口,在实现handle的方法逻辑中再定义一个抽象方法。再分别定义各个实际处理的handler继承这个抽象类,重写抽象类中定义的抽象方法,这个抽象方法,是实际业务逻辑中处理消息的方法。
public interface WxMpMessageHandler {
/**
* 处理微信推送消息.
*
* @param wxMessage 微信推送消息
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param wxMpService 服务类
* @param sessionManager session管理器
* @return xml格式的消息,如果在异步规则里处理的话,可以返回null
* @throws WxErrorException 异常
*/
WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException;
}
在微信管理类执行run方法时,定义一个微信消息路由器WxMpMessageRouter,将自定义的handler和拦截器放进路由器中进行初始化。类似如下写法:
final WxMpMessageRouter wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
wxMpMessageRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE).handler(wxmpSubscribeHandler).interceptor(wxmpMessageInterceptorImpl).end();
类似的请求报文体如下,还有签名、nonce、时间戳等参数
<xml>
<ToUserName><![CDATA[gh_28ba13224381]]></ToUserName
<FromUserName><![CDATA[微信公众号的openid]]></FromUserName> <CreateTime>1657779555</CreateTime>
<MsgType><![CDATA[text]]></MsgTyp
<Content><![CDATA[你好]]></Content
<MsgId>23733694539373153</MsgId
</xml>
使用开源SDK中的方法,WxMpService.checkSignature()进行验签。
接着用WxMpXmlMessage 将xml报文转换成消息实体进行处理
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);