前一段时间对微信渠道接入进行了技术研究,在梳理微信渠道特点的同时,对微信接入进行了开发组件的提炼。组件设计思路见图微信接入组件设计思路.jpg。
组件实现了微信开发中与微信交互的所有api,包括接收微信服务器的消息和事件、调用微信服务器的api。
一、微信服务器推送消息的接收
`IMpInputMsgDispatcher`接口定义了微信消息和事件等上行消息的接收动作和发生异常时要求微信服务器是否重发的策略。`MpInputMsgDispatcher`抽象类提供了该接口的模板实现,`SimpleInputMsgDispatcher`类实现了一个简单的来自微信服务器的上行消息和事件的分发。在收到微信服务器推送时,判断推送的类型(event or 其他消息类型),然后进行分别处理。推送的处理被委派给消息处理器`IMpMsgHandler`处理。
`IMpMsgHandler`以转换后的消息对象为入参,以Object为返回,对委派过来的消息进行业务处理。由于消息根据具体的消息类型MsgType和或事件类型Event联合确定,所以`ISupportableInputMsgHandler`接口`boolean support(WXInputMsgDataType inputMsgDataType)`方法入参以`WXInputMsgDataType`枚举类型对上行消息的数据类型进行了规定,映射了具体消息事件类型与对应数据类型的关系,`support`方法根据上行消息数据类型限定当前消息处理器所能处理的消息事件推送。
以上委派和消息处理过程中,需要将消息文本转换为消息对象,实现消息的结构化,便于后续处理,`IMpMsgConverter`接口实现了这一目标。`MpXMLMsgConverter`和`MpJsonMsgConverter`分别实现了xml和json文本数据格式与对象的转换。
由于微信服务器在正常情况下和异常情况下都存在重复推送的问题,所以`IRepetitionDecidable`接口对重复性进行了判定,在`SimpleInputMsgDispatcher`分发消息中进行判定。`SimpleUpMsgRepetitionDecisionJudge`对该接口进行了单点部署情况下的实现,对于多点部署,需要对该接口进行相应实现。
二、微信服务器api调用
MpAPI实现了对微信服务器api的调用,由于调用凭证`access_token`需要定期刷新才能持续有效,所以`IAccessTokenManager`接口规定了保鲜机制,调用者可以利用该接口获取当前可用的`access_token`。异常情况下,如果获取的`access_token`依然是失效的,可以调用`refreshAccessToken()`方法实现主动刷新并获取。`SimpleAccessTokenManager`利用`ScheduledExecutorService`提供了接口的简单实现,并依托`IAccessTokenKeepable`接口实现对`access_token`的单次获取和持有。
由于微信服务器只保持最新的和刚刚过期的`access_token`,且对其刷新次数给予配额限制,所以微信接口的调用方不应频繁刷新`access_token`,造成配额的浪费。`IAccessTokenKeepable`接口的实现`SimpleAccessTokenStandAloneKeeper`仅仅实现了单点部署环境下的刷新和持有,如果需要分布式部署,那么可以根据`IAccessTokenKeepable`接口说明,实现`access_token`在分布式部署环境下的刷新协调机制。
MpAPIClient类方便了微信API的接口调用,实现api接口调用过程的`access_token`的透明处理,即请求URI中不必在额外设置`access_token`,并且当`access_token`不合法导致调用失败时,实现重新调用。
当前组件已经实现完成,在单机环境下初步测试通过,在分布式环境下只需要实现`IAccessTokenKeepable`接口即可,微信接入组件简要类图见附图。

