一.示例代码下载
微信公众平台为开发者提供了5种语言的示例代码(包括C++、php、Java、Python和C#版本) 点击下载 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1434696670
二,微信使用xml格式的消息结构,有两种方式
1.明文模式,POST请求有signature, timestamp, nonce三个参数。它的Body为一个XML:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
2.加密模式中,增加了两个参数:encrypt_type 和 msg_signature 。它的Body 也变更为:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<Encrypt><![CDATA[encryptData]]></Encrypt>
</xml>
其中encryptData是加密后的信息,通过我们在微信开发平台配置的EncodingAESKey, Token, 以及自动生成的AppID,通过加密算法,可以验证信息的真实性,并且将真实的信息,解析成如明文的格式的XML。整条信息是加密的,因此不用担心被伪造,否则,会有风险。
三. java代码实现
1. 封装了一个AuthCheck工具类
public class AuthCheck{
public final static String Token =yourToken ;//公众平台上面自己填写的Token
public final static String EncodingAESKey = yourEncodingAESKey;//公众平台上面自己填写的43位EncodingAESKey
public final static String AppID =yourAppID;//appid(微信生成的)
/**
* 将加密后的原文进行解密重新封装
* @param request
* @param originalXml 原xml
* @return 重新解密后的xml
*/
public static String decryptMsg(HttpServletRequest request, String originalXml) {
// 微信加密签名
//String sVerifyMsgSig = request.getParameter(signature);
String msgSignature = request.getParameter("msg_signature");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
try {
WXBizMsgCrypt pc = new WXBizMsgCrypt(Token, EncodingAESKey, AppID);
return pc.decryptMsg(msgSignature, timestamp, nonce, originalXml);
} catch (AesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 对需要回复的原文进行加密重新封装
* @param request
* @param replyXml 需要回复的xml
* @return 重新加密后的xml
*/
public static String encryptMsg(HttpServletRequest request,String replyXml) {
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
try {
WXBizMsgCrypt pc = new WXBizMsgCrypt(Token, EncodingAESKey, AppID);
return pc.encryptMsg(replyXml, timestamp, nonce);
} catch (AesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
2. 处理消息如下:
@Override
public void WexHandeler(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
String notifyData = wxPayService.getNotifyStr(request);
logger.error("微信事件推送:" + notifyData);
if (StringUtils.isBlank(notifyData)) {
return;
}
String result ;
String encrypt_type =request.getParameter("encrypt_type");
//需走加解密流程
if (StringUtils.isNotBlank(encrypt_type) && encrypt_type.equals("aes")) {
//解密要求消息体
String nXmlString = AuthCheck.decryptMsg(request, notifyData);
logger.error("--nXmlString--"+nXmlString);
//履行原处理
String originalResult = handleEvent(nXmlString);
logger.error("--originalResult--"+originalResult);
result=AuthCheck.encryptMsg(request, originalResult);
//加密回复消息体
} else {//不用加密
result = handleEvent(notifyData);
}
logger.error("--result--"+result);
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println(result);
} catch (Exception e) {
logger.error("微信事件推送error:" +e.getMessage()+JSONObject.toJSONString(request.getParameterMap()));
return ;
}
return;
}