前言:
最近在研究微信公众平台的开发,玩得不亦乐乎。基本的回复功能已实现了,而且回复用到了图灵机器人的接口。其实图灵机器人已有微信接口可以直接调用。如果项目的需要,想要做个性化需求的话,用这类方式是行不通的。我现在的解决方案是,我开发的利用A作为中间层,连接微信接口与图灵机器人接口。有点扯远了,如题,微信官方为了更高的安全性,10月份推出了消息体签名验证。网上关于此项的实例不多,其实根据官方的例子,重新封装1下,就能够了。
1、准备工作:
1.已申请了相干的定阅号或服务号(可以用虚拟器,具体的方式没试过,百度1下,有很多介绍);
2.已有了原来的公众平台交互利用A;
3.依照官网提示下载相干的示例代码;
4.保证利用的JDK是1.6以上;
2、具体实现:
1.去官网设置消息加密方式,点击“开发者中心”-》“修改配置”,这里为了调试,设置为“兼容模式”:
2.将官网下载的示例代码导入利用中,我们只需关注其中重要的接口类:WXBizMsgCrypt和它的具体利用展现Program类;
3.根据自己的代码利用场景,将WXBizMsgCrypt重新封装1下:
AuthProcess.java
package cn.qtone.xxt.base.wechat.utils;
import javax.servlet.http.HttpServletRequest;
import cn.qtone.xxt.base.wechat.utils.aes.AesException;
import cn.qtone.xxt.base.wechat.utils.aes.WXBizMsgCrypt;
public class AuthProcess {
public final static String Token = "xxxx";//公众平台上面自己填写的Token
public final static String EncodingAESKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";//公众平台上面自己填写的43位EncodingAESKey
public final static String AppID = "wx488885e67d6c19e2";//利用的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;
}
}
4.找到原来自动回复接口的流程代码,在处理数据前后,加上要求数据解密,回复数据加密的流程(下面为关键代码部份):
//加密消息处理
String encrypt_type =request.getParameter("encrypt_type");
if (StringTools.nil(encrypt_type) || encrypt_type.equals("raw")) {//不用加密
// 正常的微信处理流程
result = weChatService.processWechatMag(xml);
} else {//需走加解密流程
//解密要求消息体
String nXmlString = AuthProcess.decryptMsg(request, xml);
//履行原处理
String originalResult = weChatService.processWechatMag(nXmlString);
//加密回复消息体
result = AuthProcess.encryptMsg(request, originalResult);
}
总结:经测试,以上流程是成功的,但中间出现1点小状态,需要特别说明1下,这里引述1下官方FAQ的其中1个我遇到的问题及他们的解决方案:
- 异常java.security.InvalidKeyException:illegal Key Size的解决方案:在官方网站下载JCE无穷制权限策略文件(请到官网下载对应的版本, 例如JDK7的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce⑺-download⑷32124.html下载后解压,可以看到local_policy.jar和US_export_policy.jar和readme.txt,如果安装了JRE,将两个jar文件放到%JRE_HOME%libsecurity目录下覆盖原来的文件;如果安装了JDK,将两个jar文件放到%JDK_HOME%jrelibsecurity目录下覆盖原来文件
我用的是jdk1.6.0_31,所以需要下载相干的文件并进行了覆盖,下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce⑹-download⑷29243.html