cncici 2014-11-23
前节【项目搭建】 讲述了如何搭建一个SpringMVC的Maven项目,这节我们将关注回调模式的相关事宜。
当你开启应用的回调模式时,企业号会要求你填写应用的URL、Token、EncodingAESKey三个参数。
URL是企业应用接收企业号推送请求的访问协议和地址,支持http或https协议。
Token可由企业任意填写,用于生成签名。
EncodingAESKey用于消息体的加密,是AES密钥的Base64编码。
登陆企业服务号之后,管理员可以添加企业应用:
点击添加按钮之后,按照提示创建一个WeChat的应用
点击进入WeChat配置
选中回调模式下面的进入按钮,
选择右上角的开启按钮,将会弹出对话框,让你输入接口信息:
URL 是第三方平台用来接收微信转发消息的地址,需要提供GET和POST两种方法,GET主要是用来验证URL有效性, POST主要用来接收消息。
Token 和 AESKey可以随便定义,也可以用他后面的随机获取。
我们这里定义 Token = “A8888888888888888888A”, EncodingAESKey = "A88888888888888888888888888888888888888888A"。
URL我们要填写SpringMVC的crontroller的地址,比如 http://www.xxx.com/msg.
这样我们就可以开始来设计Spring MVC中的Controller类。
创建包: com.boyi.wechat.controller
创建类: com.boyi.wechat.controller.MsgController
package com.boyi.wechat.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.boyi.wechat.utils.CommonUtils; import com.boyi.wechat.wx.msg.in.model.InMsg; import com.boyi.wechat.wx.msg.in.model.ReplyMsg; import com.boyi.wechat.wx.msg.model.MsgType; import com.boyi.wechat.wx.msg.parser.MsgParser; import com.boyi.wechat.wx.utils.WXBizMsgCrypt; import com.boyi.wechat.wx.utils.WXBizMsgCryptManager; @Controller @RequestMapping("/msg") public class MsgController { @RequestMapping(method = RequestMethod.GET) public @ResponseBody String valid(@RequestParam(value = "msg_signature") String signature, @RequestParam(value = "timestamp") String timestamp, @RequestParam(value = "nonce") String nonce, @RequestParam(value = "echostr") String echostr) throws Exception { String sEchoStr = ""; WXBizMsgCrypt wxcpt = WXBizMsgCryptManager.getChatWXBizMsgCrypt(); try { sEchoStr = wxcpt.VerifyURL(signature, timestamp, nonce, echostr); System.out.println("sEchoStr : " + sEchoStr); } catch (Exception e) { e.printStackTrace(); } return sEchoStr; } @RequestMapping(method = RequestMethod.POST) public @ResponseBody String message( @RequestParam(value = "msg_signature") String signature, @RequestParam(value = "timestamp") String timestamp, @RequestParam(value = "nonce") String nonce, @RequestBody String encryptMsg) throws Exception { String sEncryptMsg = null; WXBizMsgCrypt wxcpt = WXBizMsgCryptManager.getChatWXBizMsgCrypt(); try { String msg = wxcpt.DecryptMsg(signature, timestamp, nonce, encryptMsg); System.out.println("decode msg = " + msg); //parse the xml message to InMsg object InMsg inMsg = MsgParser.parse(msg); if (inMsg != null) { System.out.println("msg id = " + inMsg.getMsgId()); System.out.println("msg type = " + inMsg.getMsgType().name()); String content = "你刚才发的是[" + inMsg.getMsgType().name() + "]"; //create the reply message ReplyMsg replyMsg = new ReplyMsg(); replyMsg.setToUserName(inMsg.getFromUserName()); replyMsg.setFromUserName(inMsg.getToUserName()); replyMsg.setCreateTime(CommonUtils.getCurrentSecond()); replyMsg.setMsgType(MsgType.text); replyMsg.setContent(content); //convert the reply msg object to xml String xmlString = MsgParser.convert(replyMsg); System.out.println("reply message = " + xmlString); //Encrypt the xml message sEncryptMsg = wxcpt.EncryptMsg(xmlString, CommonUtils.getCurrentSecond(), nonce); System.out.println("encrypt message = " + sEncryptMsg); } } catch (Exception e) { e.printStackTrace(); } return sEncryptMsg; } }
在这个Controller里我们定义了2个方法,一个是RequestMethod 是GET的方法valid, 另外一个是POST的方法message, 由于我们在配置文件里面加入了JackSon的配置,所以就不需要去写其他的方法去获取POST发过来的数据了,直接通过@RequestBody就可以获取微信发过来的加密的消息。
WXBizMsgCrypt 这个类可以从微信官方下载到,http://qydev.weixin.qq.com/java.zip
package com.boyi.wechat.wx.utils; import java.util.HashMap; import java.util.Map; public class WXBizMsgCryptManager { public static final String sToken = "A8888888888888888888A"; /** * replace the sCorpID to your corp id */ public static final String sCorpID = "corpId"; public static final String sEncodingAESKey = "A88888888888888888888888888888888888888888A"; private static Map<String, WXBizMsgCrypt> crypts = new HashMap<String, WXBizMsgCrypt>(); public static WXBizMsgCrypt getChatWXBizMsgCrypt(){ return getWXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID); } public static WXBizMsgCrypt getWXBizMsgCrypt(String token, String encodingAesKey, String corpId) { WXBizMsgCrypt wxcpt = null; String key = corpId + "-" + token; if (crypts.containsKey(key)) { wxcpt = crypts.get(key); } else { try { wxcpt = new WXBizMsgCrypt(token, encodingAesKey, corpId); } catch (Exception e) { e.printStackTrace(); } } return wxcpt; } }
为了测试回调模式,可以先把message方法注释掉。 然后打个包,部署到你们的云主机上面,再回到回调模式页面,测试一下.
同时把下面几个选项都打开,特别是用户消息上报,如果关闭的话第三方将收不到任何消息。
本节结束,下节讲述消息的解析和发送。