前节【项目搭建】 讲述了如何搭建一个SpringMVC的Maven项目,这节我们将关注回调模式的相关事宜。

开启应用的回调模式

当你开启应用的回调模式时,企业号会要求你填写应用的URL、Token、EncodingAESKey三个参数。

URL是企业应用接收企业号推送请求的访问协议和地址,支持http或https协议。

Token可由企业任意填写,用于生成签名。

EncodingAESKey用于消息体的加密,是AES密钥的Base64编码。

登陆企业服务号之后,管理员可以添加企业应用:

java项目中如果根据业务通过企业微信向不同的员工推送不同的消息 java调用企业微信api_xml

点击添加按钮之后,按照提示创建一个WeChat的应用

java项目中如果根据业务通过企业微信向不同的员工推送不同的消息 java调用企业微信api_xml_02

点击进入WeChat配置

java项目中如果根据业务通过企业微信向不同的员工推送不同的消息 java调用企业微信api_java企业号回调模式_03

选中回调模式下面的进入按钮,

java项目中如果根据业务通过企业微信向不同的员工推送不同的消息 java调用企业微信api_spring_04

选择右上角的开启按钮,将会弹出对话框,让你输入接口信息:

java项目中如果根据业务通过企业微信向不同的员工推送不同的消息 java调用企业微信api_java企业号回调模式_05

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 crypts = new HashMap();
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方法注释掉。 然后打个包,部署到你们的云主机上面,再回到回调模式页面,测试一下.

java项目中如果根据业务通过企业微信向不同的员工推送不同的消息 java调用企业微信api_java企业号回调模式_06

同时把下面几个选项都打开,特别是用户消息上报,如果关闭的话第三方将收不到任何消息。