java 企业号 回调模式_微信企业号回调模式配置讲解 Java Servlet+Struts2版本 echostr校验失败解决...

fca0bbd9f7c03cdf8afcb78f92d01007.png

异常java.security.InvalidKeyException:illegal Key Size 也就是 echostr校验失败,请您检查是否正确解密并输出明文echostr 这个错误

企业微信登陆地址http://qy.weixin.qq.com/

da717984b17eda665d43a3049e131aa7.png

配置成功以后

b790a486e83a3d98a16f0de00c5569a6.png

Servlet 代码

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

// 微信加密签名

String msg_signature = request.getParameter("msg_signature");

// 时间戳

String timestamp = request.getParameter("timestamp");

// 随机数

String nonce = request.getParameter("nonce");

// 随机字符串

String echostr = request.getParameter("echostr");

// 打印请求地址

System.out.println("request=" + request.getRequestURL());

// 流

PrintWriter out = response.getWriter();

// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败

String result = null;

try {

WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(ParamesAPI.token, ParamesAPI.encodingAESKey, ParamesAPI.corpId);

// 验证URL函数

result = wxcpt.VerifyURL(msg_signature, timestamp, nonce, echostr);

} catch (AesException e) {

e.printStackTrace();

}

if (result == null) {

// result为空,赋予token

result = ParamesAPI.token;

}

// 拼接请求参数

String str = msg_signature + " " + timestamp + " " + nonce + " " + echostr;

// 打印参数+地址+result

System.out.println("Exception:" + result + " " + request.getRequestURL() + " " + "FourParames:" + str);

String info = "Exception:" + result + " " + request.getRequestURL() + " " + "FourParames:" + str;

log.info(info);

out.print(result);

out.close();

out = null;

}

官方回调页面的代码

import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.NodeList;

import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilderFactory;

import com.qq.weixin.mp.aes.WXBizMsgCrypt;

public class Sample {

public static void main(String[] args) throws Exception {

String sToken = "QDG6eK";

String sCorpID = "wx5823bf96d3bd56c7";

String sEncodingAESKey = "jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C";

WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);

/*

------------使用示例一:验证回调URL---------------

*企业开启回调模式时,企业号会向验证url发送一个get请求

假设点击验证时,企业收到类似请求:

* GET /cgi-bin/wxpush?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3&timestamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D

* HTTP/1.1 Host: qy.weixin.qq.com

接收到该请求时,企业应        1.解析出Get请求的参数,包括消息体签名(msg_signature),时间戳(timestamp),随机数字串(nonce)以及公众平台推送过来的随机加密字符串(echostr),

这一步注意作URL解码。

2.验证消息体签名的正确性

3. 解密出echostr原文,将原文当作Get请求的response,返回给公众平台

第2,3步可以用公众平台提供的库函数VerifyURL来实现。

*/

// 解析出url上的参数值如下:

// String sVerifyMsgSig = HttpUtils.ParseUrl("msg_signature");

String sVerifyMsgSig = "5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3";

// String sVerifyTimeStamp = HttpUtils.ParseUrl("timestamp");

String sVerifyTimeStamp = "1409659589";

// String sVerifyNonce = HttpUtils.ParseUrl("nonce");

String sVerifyNonce = "263014780";

// String sVerifyEchoStr = HttpUtils.ParseUrl("echostr");

String sVerifyEchoStr = "P9nAzCzyDtyTWESHep1vC5X9xho/qYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp+4RPcs8TgAE7OaBO+FZXvnaqQ==";

String sEchoStr; //需要返回的明文

try {

sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,

sVerifyNonce, sVerifyEchoStr);

System.out.println("verifyurl echostr: " + sEchoStr);

// 验证URL成功,将sEchoStr返回

// HttpUtils.SetResponse(sEchoStr);

} catch (Exception e) {

//验证URL失败,错误原因请查看异常

e.printStackTrace();

}

/*

------------使用示例二:对用户回复的消息解密---------------

用户回复消息或者点击事件响应时,企业会收到回调消息,此消息是经过公众平台加密之后的密文以post形式发送给企业,密文格式请参考官方文档

假设企业收到公众平台的回调消息如下:

POST /cgi-bin/wxpush? msg_signature=477715d11cdb4164915debcba66cb864d751f3e6&timestamp=1409659813&nonce=1372623149 HTTP/1.1

Host: qy.weixin.qq.com

Content-Length: 613

企业收到post请求之后应该        1.解析出url上的参数,包括消息体签名(msg_signature),时间戳(timestamp)以及随机数字串(nonce)

2.验证消息体签名的正确性。

3.将post请求的数据进行xml解析,并将标签的内容进行解密,解密出来的明文即是用户回复消息的明文,明文格式请参考官方文档

第2,3步可以用公众平台提供的库函数DecryptMsg来实现。

*/

// String sReqMsgSig = HttpUtils.ParseUrl("msg_signature");

String sReqMsgSig = "477715d11cdb4164915debcba66cb864d751f3e6";

// String sReqTimeStamp = HttpUtils.ParseUrl("timestamp");

String sReqTimeStamp = "1409659813";

// String sReqNonce = HttpUtils.ParseUrl("nonce");

String sReqNonce = "1372623149";

// post请求的密文数据

// sReqData = HttpUtils.PostData();

String sReqData = "";

try {

String sMsg = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData);

System.out.println("after decrypt msg: " + sMsg);

// TODO: 解析出明文xml标签的内容进行处理

// For example:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

DocumentBuilder db = dbf.newDocumentBuilder();

StringReader sr = new StringReader(sMsg);

InputSource is = new InputSource(sr);

Document document = db.parse(is);

Element root = document.getDocumentElement();

NodeList nodelist1 = root.getElementsByTagName("Content");

String Content = nodelist1.item(0).getTextContent();

System.out.println("Content:" + Content);

} catch (Exception e) {

// TODO

// 解密失败,失败原因请查看异常

e.printStackTrace();

}

/*

------------使用示例三:企业回复用户消息的加密---------------

企业被动回复用户的消息也需要进行加密,并且拼接成密文格式的xml串。

假设企业需要回复用户的明文如下:

1348831860

1234567890123456

128

为了将此段明文回复给用户,企业应:            1.自己生成时间时间戳(timestamp),随机数字串(nonce)以便生成消息体签名,也可以直接用从公众平台的post url上解析出的对应值。

2.将明文加密得到密文。    3.用密文,步骤1生成的timestamp,nonce和企业在公众平台设定的token生成消息体签名。            4.将密文,消息体签名,时间戳,随机数字串拼接成xml格式的字符串,发送给企业。

以上2,3,4步可以用公众平台提供的库函数EncryptMsg来实现。

*/

String sRespData = "13488318601234567890123456128";

try{

String sEncryptMsg = wxcpt.EncryptMsg(sRespData, sReqTimeStamp, sReqNonce);

System.out.println("after encrypt sEncrytMsg: " + sEncryptMsg);

// 加密成功

// TODO:

// HttpUtils.SetResponse(sEncryptMsg);

}

catch(Exception e)

{

e.printStackTrace();

// 加密失败

}

}

}

来重点了:echostr校验失败,请您检查是否正确解密并输出明文echostr

有可能会遇到这样的错误。大家就百度搜索也找不到。因为官方提供了解决方案。所以,仔细

看官方提供的验证加密的源代码是有作用的。

说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案

* 在官方网站下载JCE无限制权限策略文件(JDK7的下载地址:

*   http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

* 下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt

* 如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件

* 如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件

‍Struts2

public String execute() throws Exception {

// 将请求、响应的编码均设置为UTF-8(防止中文乱码)

HttpServletRequest request = ServletActionContext.getRequest();

HttpServletResponse response = ServletActionContext.getResponse();

request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");

//微信加密签名

String msg_signature = request.getParameter("msg_signature");

// 时间戳

String timestamp = request.getParameter("timestamp");

// 随机数

String nonce = request.getParameter("nonce");

// 随机字符串

String echostr = request.getParameter("echostr");

PrintWriter out = response.getWriter();

String result = null;

// 请求校验

try{

WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(ParamesAPI.token, ParamesAPI.encodingAESKey, ParamesAPI.corpId);

//验证URL函数

result = wxcpt.VerifyURL(msg_signature, timestamp, nonce, echostr);

if(result==null){

result = ParamesAPI.token;

}else{

out.print(result);

}

}catch (Exception e) {

e.printStackTrace();

log.error("请求错误,稍后再试",e);

}

out.close();

out = null;

return null;

}

个人微博http://weibo.com/zxshuai319

公开QQ  783021975

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值