2.4)接收微信服务器发来的消息
当你验证服务器有消息成功后,微信服务器就会把你的公众号任何事件和消息,以post请求推送到你验证的那个url地址上。
所以,把DemoServlet.java的doPost方法完善一下,并创建一个简单的WxMessageHandler。
- 创建类DemoHandler.java 实现 WxMessageHandler接口
/**
* 示例:DemoHandler
* 目的:返回用户 “恭喜你猜对了”
* @author antgan
* @date 2016/12/15
*
*/
public class DemoHandler implements WxMessageHandler{
@Override
public WxXmlOutMessage handle(WxXmlMessage wxMessage, Map<String, Object> context, IService iService)
throws WxErrorException {
//必须以build()作为结尾,否则不生效。
WxXmlOutMessage xmlOutMsg = WxXmlOutMessage.TEXT().content("恭喜你猜对了").toUser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()).build();
return xmlOutMsg;
}
}
- 完善doPost方法,这里示例是判断了消息的加密模式,如果是明文模式,可以不用加解密消息。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
// 返回消息给微信服务器
PrintWriter out = response.getWriter();
// 获取encrypt_type 消息加解密方式标识
String encrypt_type = request.getParameter("encrypt_type");
// 创建一个路由器
WxMessageRouter router = new WxMessageRouter(iService);
try {
// 判断消息加解密方式,如果是加密模式。encrypt_type==aes
if (encrypt_type != null && "aes".equals(encrypt_type)) {
// String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String msg_signature = request.getParameter("msg_signature");
// 微信服务器推送过来的加密消息是XML格式。使用WxXmlMessage中的decryptMsg()解密得到明文。
WxXmlMessage wx = WxXmlMessage.decryptMsg(request.getInputStream(), WxConfig.getInstance(), timestamp,
nonce, msg_signature);
System.out.println("消息:\n " + wx.toString());
// 添加规则;这里的规则是指所有消息都交给交给DemoHandler处理
// 注意!!每一个规则,必须由end()或者next()结束。不然不会生效。
// end()是指消息进入该规则后不再进入其他规则。 而next()是指消息进入了一个规则后,如果满足其他规则也能进入,处理。
router.rule().handler(new DemoHandler()).end();
// 把消息传递给路由器进行处理,得到最后一个handler处理的结果
WxXmlOutMessage xmlOutMsg = router.route(wx);
if (xmlOutMsg != null) {
// 将要返回的消息加密,返回
out.print(WxXmlOutMessage.encryptMsg(WxConfig.getInstance(), xmlOutMsg.toXml(), timestamp, nonce));// 返回给用户。
}
//如果是明文模式,执行以下语句
} else {
// 微信服务器推送过来的是XML格式。
WxXmlMessage wx = XStreamTransformer.fromXml(WxXmlMessage.class, request.getInputStream());
System.out.println("消息:\n " + wx.toString());
// 添加规则;这里的规则是指所有消息都交给DemoHandler处理
// 注意!!每一个规则,必须由end()或者next()结束。不然不会生效。
// end()是指消息进入该规则后不再进入其他规则。 而next()是指消息进入了一个规则后,如果满足其他规则也能进入,处理。
router.rule().handler(new DemoHandler()).end();
// 把消息传递给路由器进行处理
WxXmlOutMessage xmlOutMsg = router.route(wx);
if (xmlOutMsg != null)
out.print(xmlOutMsg.toXml());// 因为是明文,所以不用加密,直接返回给用户。
}
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}
这样子写的效果就是:公众号后台接收所有类型的消息,都交给DemoHandler处理器处理,最后返回了一句“恭喜你猜对了”给用户。
是不是很简单?
看到这里你已经入门了。
接下来加入匹配器Matcher和Interceptor拦截器来处理更加复杂的业务。