微信公众号开发java版-消息回复(普通文字消息和语音消息)
<pre>本文介绍微信公众号消息自动回复功能的开发,开发语言 java<br>话不多说,直接上代码<br><br>1.控制器代码</pre><div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.controller;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.springframework.context.annotation.Scope;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.springframework.web.bind.annotation.RequestMapping;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.springframework.web.bind.annotation.RequestMethod;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.springframework.web.bind.annotation.ResponseBody;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.springframework.web.bind.annotation.RestController;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.WechatSignUtil;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat.AuthProcess;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat.MessageUtil;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> javax.servlet.http.HttpServletRequest;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> javax.servlet.http.HttpServletResponse;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.io.IOException;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.HashMap;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.Map;
@Scope(</span>"prototype"<span style="color: rgba(0, 0, 0, 1)">)
@RestController</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> NotifyController {
@RequestMapping(value </span>= "notify",method =<span style="color: rgba(0, 0, 0, 1)"> { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String wechatNotify(HttpServletRequest request, HttpServletResponse response, String signature, String timestamp,
String nonce, String echostr) </span><span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> IOException {
</span><span style="color: rgba(0, 0, 255, 1)">boolean</span> isGet = request.getMethod().toLowerCase().equals("get"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (isGet) {
</span><span style="color: rgba(0, 0, 255, 1)">boolean</span> isOk =<span style="color: rgba(0, 0, 0, 1)"> WechatSignUtil.checkSignature(signature, timestamp, nonce);
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (isOk)
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> echostr;
</span><span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
String resp </span>= ""<span style="color: rgba(0, 0, 0, 1)">;
request.setCharacterEncoding(</span>"UTF-8"<span style="color: rgba(0, 0, 0, 1)">);
response.setCharacterEncoding(</span>"UTF-8"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
Map</span><String,String> map =<span style="color: rgba(0, 0, 0, 1)"> MessageUtil.xmlToMap(request);
String xml </span>= "<xml><ToUserName>"+map.get("ToUserName")+"</ToUserName><Encrypt>" +map.get("Encrypt")+
"</Encrypt></xml>"<span style="color: rgba(0, 0, 0, 1)">;
String result </span>=<span style="color: rgba(0, 0, 0, 1)"> AuthProcess.decryptMsg(request, xml);
Map</span><String, Object> req =<span style="color: rgba(0, 0, 0, 1)"> MessageUtil.xmlStr2Map(result);
</span><span style="color: rgba(0, 0, 255, 1)">boolean</span> hasEvent = req.containsKey("Event"<span style="color: rgba(0, 0, 0, 1)">);
String respXml </span>= ""<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (hasEvent) {
String event </span>= req.get("Event"<span style="color: rgba(0, 0, 0, 1)">).toString();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> ("subscribe"<span style="color: rgba(0, 0, 0, 1)">.equals(event)) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用户订阅公众号行为</span>
HashMap<String, Object> mapXml = <span style="color: rgba(0, 0, 255, 1)">new</span> HashMap<><span style="color: rgba(0, 0, 0, 1)">();
mapXml.put(</span>"ToUserName",req.get("FromUserName"<span style="color: rgba(0, 0, 0, 1)">));
mapXml.put(</span>"FromUserName",req.get("ToUserName"<span style="color: rgba(0, 0, 0, 1)">));
mapXml.put(</span>"CreateTime",req.get("CreateTime"<span style="color: rgba(0, 0, 0, 1)">));
mapXml.put(</span>"MsgType","text"<span style="color: rgba(0, 0, 0, 1)">);
mapXml.put(</span>"Content","感谢关注"<span style="color: rgba(0, 0, 0, 1)">);
respXml </span>=<span style="color: rgba(0, 0, 0, 1)"> MessageUtil.map2Xmlstring(mapXml);
}
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
String msgType </span>= req.get("MsgType"<span style="color: rgba(0, 0, 0, 1)">).toString();
String receive </span>= ""<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> ("text"<span style="color: rgba(0, 0, 0, 1)">.equals(msgType)){
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">普通文字消息</span>
receive = req.get("Content"<span style="color: rgba(0, 0, 0, 1)">).toString();
} </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> ("voice"<span style="color: rgba(0, 0, 0, 1)">.equals(msgType)){
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">语音消息
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注意:这里Recognition拿到的直接就是语音消息转化之后的文字内容!!!直接用就好了</span>
receive = req.get("Recognition"<span style="color: rgba(0, 0, 0, 1)">).toString();
}
respXml </span>=<span style="color: rgba(0, 0, 0, 1)"> sendMsg(req,receive);
}
resp </span>=<span style="color: rgba(0, 0, 0, 1)"> AuthProcess.encryptMsg(request, respXml.trim());
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> resp;
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
e.printStackTrace();
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> resp;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> String sendMsg(Map<String, Object><span style="color: rgba(0, 0, 0, 1)"> req,String receive) {
HashMap</span><String, Object> mapXml = <span style="color: rgba(0, 0, 255, 1)">new</span> HashMap<><span style="color: rgba(0, 0, 0, 1)">();
mapXml.put(</span>"ToUserName",req.get("FromUserName"<span style="color: rgba(0, 0, 0, 1)">));
mapXml.put(</span>"FromUserName",req.get("ToUserName"<span style="color: rgba(0, 0, 0, 1)">));
mapXml.put(</span>"CreateTime",req.get("CreateTime"<span style="color: rgba(0, 0, 0, 1)">));
mapXml.put(</span>"MsgType","text"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据receive组装回复的内容</span>
mapXml.put("Content","回复的消息内容"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> MessageUtil.map2Xmlstring(mapXml);
}
}</span></pre>
</div>
<p> </p>
<p>2.杂七杂八的一些类,上面控制器用到的</p>
<div class="cnblogs_code"><img id="code_img_closed_7f9c5a82-25f5-41db-8603-9a99a1c43d02" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_7f9c5a82-25f5-41db-8603-9a99a1c43d02" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_7f9c5a82-25f5-41db-8603-9a99a1c43d02" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat;
@SuppressWarnings(</span>"serial"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> AesException <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> Exception {
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> OK = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> ValidateSignatureError = -40001<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> ParseXmlError = -40002<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> ComputeSignatureError = -40003<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> IllegalAesKey = -40004<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> ValidateAppidError = -40005<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> EncryptAESError = -40006<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> DecryptAESError = -40007<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> IllegalBuffer = -40008<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">public final static int EncodeBase64Error = -40009;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">public final static int DecodeBase64Error = -40010;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">public final static int GenReturnXmlError = -40011;</span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> code;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String getMessage(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> code) {
</span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (code) {
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> ValidateSignatureError:
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "签名验证错误"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> ParseXmlError:
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "xml解析失败"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> ComputeSignatureError:
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "sha加密生成签名失败"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> IllegalAesKey:
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "SymmetricKey非法"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> ValidateAppidError:
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "appid校验失败"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> EncryptAESError:
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "aes加密失败"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> DecryptAESError:
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "aes解密失败"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> IllegalBuffer:
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "解密后得到的buffer非法"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> case EncodeBase64Error:
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> return "base64加密错误";
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> case DecodeBase64Error:
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> return "base64解密错误";
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> case GenReturnXmlError:
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> return "xml生成失败";</span>
<span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> cannot be</span>
<span style="color: rgba(0, 0, 0, 1)"> }
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getCode() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> code;
}
AesException(</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> code) {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">(getMessage(code));
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.code =<span style="color: rgba(0, 0, 0, 1)"> code;
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code"><img id="code_img_closed_3f5582cc-63b2-46a8-bdde-4f7230f846c2" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_3f5582cc-63b2-46a8-bdde-4f7230f846c2" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_3f5582cc-63b2-46a8-bdde-4f7230f846c2" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> javax.servlet.http.HttpServletRequest;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> AuthProcess {
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 将加密后的原文进行解密重新封装
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> request
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> originalXml 原xml
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 重新解密后的xml
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> StringdecryptMsg(HttpServletRequest request,String originalXml) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 微信加密签名
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">String sVerifyMsgSig = request.getParameter("signature");</span>
String msgSignature = request.getParameter("msg_signature"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 时间戳</span>
String timestamp = request.getParameter("timestamp"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 随机数</span>
String nonce = request.getParameter("nonce"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
WXBizMsgCrypt pc </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> WXBizMsgCrypt("your token", "your EncodingAESKey", "your appid"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> pc.decryptMsg(msgSignature, timestamp, nonce, originalXml);
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (AesException e) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO Auto-generated catch block</span>
<span style="color: rgba(0, 0, 0, 1)"> e.printStackTrace();
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 对需要回复的原文进行加密重新封装
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> request
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> replyXml 需要回复的xml
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 重新加密后的xml
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> StringencryptMsg(HttpServletRequest request, String replyXml) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 时间戳</span>
String timestamp = request.getParameter("timestamp"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 随机数</span>
String nonce = request.getParameter("nonce"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
WXBizMsgCrypt pc </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> WXBizMsgCrypt("your token", "your EncodingAESKey", "your appid"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> pc.encryptMsg(replyXml, timestamp, nonce);
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (AesException e) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO Auto-generated catch block</span>
<span style="color: rgba(0, 0, 0, 1)"> e.printStackTrace();
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code"><img id="code_img_closed_d20db968-c02b-4fd9-9010-c72a907af680" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_d20db968-c02b-4fd9-9010-c72a907af680" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_d20db968-c02b-4fd9-9010-c72a907af680" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.ArrayList;
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> ByteGroup {
ArrayList</span><Byte> byteContainer = <span style="color: rgba(0, 0, 255, 1)">new</span> ArrayList<Byte><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] toBytes() {
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < byteContainer.size(); i++<span style="color: rgba(0, 0, 0, 1)">) {
bytes </span>=<span style="color: rgba(0, 0, 0, 1)"> byteContainer.get(i);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bytes;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> ByteGroup addBytes(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] bytes) {
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)"> b : bytes) {
byteContainer.add(b);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> size() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> byteContainer.size();
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code"><img id="code_img_closed_b68a4d89-6079-4e52-9fd7-5f541bc84607" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b68a4d89-6079-4e52-9fd7-5f541bc84607" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b68a4d89-6079-4e52-9fd7-5f541bc84607" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> com.thoughtworks.xstream.XStream;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.apache.http.util.TextUtils;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.dom4j.Document;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.dom4j.DocumentException;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.dom4j.DocumentHelper;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.dom4j.Element;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.dom4j.io.SAXReader;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> javax.servlet.http.HttpServletRequest;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.io.IOException;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.io.InputStream;
</span><span style="color: rgba(0, 0, 255, 1)">import</span> java.util.*<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MessageUtil {
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String MESSAGE_TEXT = "text"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String MESSAGE_IMAGE = "image"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String MESSAGE_VOICE = "voice"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String MESSAGE_VIDEO = "video"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String MESSAGE_LINK = "link"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String MESSAGE_LOCATION = "location"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String MESSAGE_EVENT = "event"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String EVENT_SUB = "subscribe"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String EVENT_UNSUB = "unsubscribe"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String EVENT_CLICK = "CLICK"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String EVENT_VIEW = "VIEW"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* xml转为map
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> request
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)">
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> DocumentException
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> IOException
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> Map<String, String> xmlToMap(HttpServletRequest request ) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> DocumentException, IOException
{
Map</span><String,String> map = <span style="color: rgba(0, 0, 255, 1)">new</span> HashMap<String, String><span style="color: rgba(0, 0, 0, 1)">();
SAXReader reader </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SAXReader();
InputStream ins </span>=<span style="color: rgba(0, 0, 0, 1)"> request.getInputStream();
Document doc </span>=<span style="color: rgba(0, 0, 0, 1)"> reader.read(ins);
Element root </span>=<span style="color: rgba(0, 0, 0, 1)"> doc.getRootElement();
List</span><Element> list =<span style="color: rgba(0, 0, 0, 1)"> root.elements();
</span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (Element e : list) {
map.put(e.getName(), e.getText());
}
ins.close();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> map;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> String textMessageToXml(TextMessage textMessage){
XStream xstream </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> XStream();
xstream.alias(</span>"xml"<span style="color: rgba(0, 0, 0, 1)">, textMessage.getClass());
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> xstream.toXML(textMessage);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> Map<String,Object><span style="color: rgba(0, 0, 0, 1)"> xmlStr2Map(String xmlStr){
Map</span><String,Object> map = <span style="color: rgba(0, 0, 255, 1)">new</span> HashMap<String,Object><span style="color: rgba(0, 0, 0, 1)">();
Document doc;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
doc </span>=<span style="color: rgba(0, 0, 0, 1)"> DocumentHelper.parseText(xmlStr);
Element root </span>=<span style="color: rgba(0, 0, 0, 1)"> doc.getRootElement();
List children </span>=<span style="color: rgba(0, 0, 0, 1)"> root.elements();
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(children != <span style="color: rgba(0, 0, 255, 1)">null</span> && children.size() > 0<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < children.size(); i++<span style="color: rgba(0, 0, 0, 1)">) {
Element child </span>=<span style="color: rgba(0, 0, 0, 1)"> (Element)children.get(i);
map.put(child.getName(), child.getTextTrim());
}
}
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (DocumentException e) {
e.printStackTrace();
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> map;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String map2Xmlstring(Map<String,Object><span style="color: rgba(0, 0, 0, 1)"> map){
StringBuffer sb </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> StringBuffer(""<span style="color: rgba(0, 0, 0, 1)">);
sb.append(</span>"<xml>"<span style="color: rgba(0, 0, 0, 1)">);
Set</span><String> set =<span style="color: rgba(0, 0, 0, 1)"> map.keySet();
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(Iterator<String> it =<span style="color: rgba(0, 0, 0, 1)"> set.iterator(); it.hasNext();){
String key </span>=<span style="color: rgba(0, 0, 0, 1)"> it.next();
Object value </span>=<span style="color: rgba(0, 0, 0, 1)"> map.get(key);
sb.append(</span>"<").append(key).append(">"<span style="color: rgba(0, 0, 0, 1)">);
sb.append(value);
sb.append(</span>"</").append(key).append(">"<span style="color: rgba(0, 0, 0, 1)">);
}
sb.append(</span>"</xml>"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sb.toString();
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String map2XmlstringWithHead(Map<String,Object><span style="color: rgba(0, 0, 0, 1)"> map,String head){
StringBuffer sb </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> StringBuffer(""<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">TextUtils.isEmpty(head)) {
sb.append(</span>"<"+head+">"<span style="color: rgba(0, 0, 0, 1)">);
}
Set</span><String> set =<span style="color: rgba(0, 0, 0, 1)"> map.keySet();
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(Iterator<String> it =<span style="color: rgba(0, 0, 0, 1)"> set.iterator(); it.hasNext();){
String key </span>=<span style="color: rgba(0, 0, 0, 1)"> it.next();
Object value </span>=<span style="color: rgba(0, 0, 0, 1)"> map.get(key);
sb.append(</span>"<").append(key).append(">"<span style="color: rgba(0, 0, 0, 1)">);
sb.append(value);
sb.append(</span>"</").append(key).append(">"<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">TextUtils.isEmpty(head)) {
sb.append(</span>"</"+head+">"<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sb.toString();
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code"><img id="code_img_closed_b142238c-5091-44ec-a90a-24729b72c2b1" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b142238c-5091-44ec-a90a-24729b72c2b1" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b142238c-5091-44ec-a90a-24729b72c2b1" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ------------------------------------------------------------------------</span>
<span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.nio.charset.Charset;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.Arrays;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 提供基于PKCS7算法的加解密接口.
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> PKCS7Encoder {
</span><span style="color: rgba(0, 0, 255, 1)">static</span> Charset CHARSET = Charset.forName("utf-8"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> BLOCK_SIZE = 32<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 获得对明文进行补位填充的字节.
*
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> count 需要进行填充补位操作的明文字节个数
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 补齐用的字节数组
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] encode(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> count) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 计算需要填充的位数</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> amountToPad = BLOCK_SIZE - (count %<span style="color: rgba(0, 0, 0, 1)"> BLOCK_SIZE);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (amountToPad == 0<span style="color: rgba(0, 0, 0, 1)">) {
amountToPad </span>=<span style="color: rgba(0, 0, 0, 1)"> BLOCK_SIZE;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获得补位所用的字符</span>
<span style="color: rgba(0, 0, 255, 1)">char</span> padChr =<span style="color: rgba(0, 0, 0, 1)"> chr(amountToPad);
String tmp </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> String();
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> index = 0; index < amountToPad; index++<span style="color: rgba(0, 0, 0, 1)">) {
tmp </span>+=<span style="color: rgba(0, 0, 0, 1)"> padChr;
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> tmp.getBytes(CHARSET);
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 删除解密后明文的补位字符
*
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> decrypted 解密后的明文
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 删除补位字符后的明文
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] decode(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] decrypted) {
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pad = (<span style="color: rgba(0, 0, 255, 1)">int</span>) decrypted;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (pad < 1 || pad > 32<span style="color: rgba(0, 0, 0, 1)">) {
pad </span>= 0<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> Arrays.copyOfRange(decrypted, 0, decrypted.length -<span style="color: rgba(0, 0, 0, 1)"> pad);
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
*
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> a 需要转化的数字
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 转化得到的字符
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">char</span> chr(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> a) {
</span><span style="color: rgba(0, 0, 255, 1)">byte</span> target = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (a & 0xFF<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> (<span style="color: rgba(0, 0, 255, 1)">char</span><span style="color: rgba(0, 0, 0, 1)">) target;
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code"><img id="code_img_closed_c0aa2be1-ea44-4b75-a61e-31724ee9e1a4" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_c0aa2be1-ea44-4b75-a61e-31724ee9e1a4" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_c0aa2be1-ea44-4b75-a61e-31724ee9e1a4" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ------------------------------------------------------------------------</span>
<span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.security.MessageDigest;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.Arrays;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* SHA1 class
*
* 计算公众平台的消息签名接口.
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SHA1 {
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 用SHA1算法生成安全签名
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> token 票据
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> timestamp 时间戳
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> nonce 随机字符串
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> encrypt 密文
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 安全签名
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> com.qq.weixin.mp.aes.AesException
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String getSHA1(String token, String timestamp, String nonce, String encrypt) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> AesException
{
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
String[] array </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> String[] { token, timestamp, nonce, encrypt };
StringBuffer sb </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StringBuffer();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 字符串排序</span>
<span style="color: rgba(0, 0, 0, 1)"> Arrays.sort(array);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < 4; i++<span style="color: rgba(0, 0, 0, 1)">) {
sb.append(array);
}
String str </span>=<span style="color: rgba(0, 0, 0, 1)"> sb.toString();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> SHA1签名生成</span>
MessageDigest md = MessageDigest.getInstance("SHA-1"<span style="color: rgba(0, 0, 0, 1)">);
md.update(str.getBytes());
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] digest =<span style="color: rgba(0, 0, 0, 1)"> md.digest();
StringBuffer hexstr </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StringBuffer();
String shaHex </span>= ""<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < digest.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
shaHex </span>= Integer.toHexString(digest & 0xFF<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (shaHex.length() < 2<span style="color: rgba(0, 0, 0, 1)">) {
hexstr.append(</span>0<span style="color: rgba(0, 0, 0, 1)">);
}
hexstr.append(shaHex);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> hexstr.toString();
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
e.printStackTrace();
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AesException(AesException.ComputeSignatureError);
}
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code"><img id="code_img_closed_2193f5c4-e451-4cde-b46a-8013f83f0d91" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_2193f5c4-e451-4cde-b46a-8013f83f0d91" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_2193f5c4-e451-4cde-b46a-8013f83f0d91" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> TextMessage {
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String ToUserName;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String FromUserName;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> CreateTime;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String MsgType;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String Content;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getToUserName() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ToUserName;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setToUserName(String toUserName) {
ToUserName </span>=<span style="color: rgba(0, 0, 0, 1)"> toUserName;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getFromUserName() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> FromUserName;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setFromUserName(String fromUserName) {
FromUserName </span>=<span style="color: rgba(0, 0, 0, 1)"> fromUserName;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getCreateTime() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> CreateTime;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setCreateTime(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> createTime) {
CreateTime </span>=<span style="color: rgba(0, 0, 0, 1)"> createTime;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getMsgType() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> MsgType;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setMsgType(String msgType) {
MsgType </span>=<span style="color: rgba(0, 0, 0, 1)"> msgType;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getContent() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Content;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setContent(String content) {
Content </span>=<span style="color: rgba(0, 0, 0, 1)"> content;
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code"><img id="code_img_closed_8c95ec38-fb65-43eb-81da-7357ed77709c" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_8c95ec38-fb65-43eb-81da-7357ed77709c" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_8c95ec38-fb65-43eb-81da-7357ed77709c" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ------------------------------------------------------------------------</span>
<span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 针对org.apache.commons.codec.binary.Base64,
* 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
* 官方下载地址:</span><span style="color: rgba(0, 128, 0, 1); text-decoration: underline">http://commons.apache.org/proper/commons-codec/download_codec.cgi</span>
<span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.apache.commons.codec.binary.Base64;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> javax.crypto.Cipher;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> javax.crypto.spec.IvParameterSpec;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> javax.crypto.spec.SecretKeySpec;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.nio.charset.Charset;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.Arrays;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.Random;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 提供接收和推送给公众平台消息的加解密接口(UTF8编码的字符串).
* <ol>
* <li>第三方回复加密消息给公众平台</li>
* <li>第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。</li>
* </ol>
* 说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案
* <ol>
* <li>在官方网站下载JCE无限制权限策略文件(JDK7的下载地址:
* </span><span style="color: rgba(0, 128, 0, 1); text-decoration: underline">http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html</span><span style="color: rgba(0, 128, 0, 1)"></li>
* <li>下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt</li>
* <li>如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件</li>
* <li>如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件</li>
* </ol>
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> WXBizMsgCrypt {
</span><span style="color: rgba(0, 0, 255, 1)">static</span> Charset CHARSET = Charset.forName("utf-8"<span style="color: rgba(0, 0, 0, 1)">);
Base64 base64 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Base64();
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] aesKey;
String token;
String appId;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 构造函数
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> token 公众平台上,开发者设置的token
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> encodingAesKey 公众平台上,开发者设置的EncodingAESKey
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> appId 公众平台appid
*
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> AesException 执行失败,请查看该异常的错误码和具体的错误信息
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> WXBizMsgCrypt(String token, String encodingAesKey, String appId) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> AesException {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (encodingAesKey.length() != 43<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AesException(AesException.IllegalAesKey);
}
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.token =<span style="color: rgba(0, 0, 0, 1)"> token;
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.appId =<span style="color: rgba(0, 0, 0, 1)"> appId;
aesKey </span>= Base64.decodeBase64(encodingAesKey + "="<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 生成4个字节的网络字节序</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] getNetworkBytesOrder(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> sourceNumber) {
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] orderBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>;
orderBytes[</span>3] = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (sourceNumber & 0xFF<span style="color: rgba(0, 0, 0, 1)">);
orderBytes[</span>2] = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (sourceNumber >> 8 & 0xFF<span style="color: rgba(0, 0, 0, 1)">);
orderBytes[</span>1] = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (sourceNumber >> 16 & 0xFF<span style="color: rgba(0, 0, 0, 1)">);
orderBytes[</span>0] = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (sourceNumber >> 24 & 0xFF<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> orderBytes;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 还原4个字节的网络字节序</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> recoverNetworkBytesOrder(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] orderBytes) {
</span><span style="color: rgba(0, 0, 255, 1)">int</span> sourceNumber = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < 4; i++<span style="color: rgba(0, 0, 0, 1)">) {
sourceNumber </span><<= 8<span style="color: rgba(0, 0, 0, 1)">;
sourceNumber </span>|= orderBytes & 0xff<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sourceNumber;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 随机生成16位字符串</span>
<span style="color: rgba(0, 0, 0, 1)"> String getRandomStr() {
String base </span>= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"<span style="color: rgba(0, 0, 0, 1)">;
Random random </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Random();
StringBuffer sb </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StringBuffer();
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < 16; i++<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">int</span> number =<span style="color: rgba(0, 0, 0, 1)"> random.nextInt(base.length());
sb.append(base.charAt(number));
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sb.toString();
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 对明文进行加密.
*
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> text 需要加密的明文
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 加密后base64编码的字符串
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> AesException aes加密失败
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
String encrypt(String randomStr, String text) </span><span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> AesException {
ByteGroup byteCollector </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ByteGroup();
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] randomStrBytes =<span style="color: rgba(0, 0, 0, 1)"> randomStr.getBytes(CHARSET);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] textBytes =<span style="color: rgba(0, 0, 0, 1)"> text.getBytes(CHARSET);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] networkBytesOrder =<span style="color: rgba(0, 0, 0, 1)"> getNetworkBytesOrder(textBytes.length);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] appidBytes =<span style="color: rgba(0, 0, 0, 1)"> appId.getBytes(CHARSET);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> randomStr + networkBytesOrder + text + appid</span>
<span style="color: rgba(0, 0, 0, 1)"> byteCollector.addBytes(randomStrBytes);
byteCollector.addBytes(networkBytesOrder);
byteCollector.addBytes(textBytes);
byteCollector.addBytes(appidBytes);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ... + pad: 使用自定义的填充方式对明文进行补位填充</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] padBytes =<span style="color: rgba(0, 0, 0, 1)"> PKCS7Encoder.encode(byteCollector.size());
byteCollector.addBytes(padBytes);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获得最终的字节流, 未加密</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] unencrypted =<span style="color: rgba(0, 0, 0, 1)"> byteCollector.toBytes();
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置加密模式为AES的CBC模式</span>
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"<span style="color: rgba(0, 0, 0, 1)">);
SecretKeySpec keySpec </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> SecretKeySpec(aesKey, "AES"<span style="color: rgba(0, 0, 0, 1)">);
IvParameterSpec iv </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> IvParameterSpec(aesKey, 0, 16<span style="color: rgba(0, 0, 0, 1)">);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 加密</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] encrypted =<span style="color: rgba(0, 0, 0, 1)"> cipher.doFinal(unencrypted);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用BASE64对加密后的字符串进行编码</span>
String base64Encrypted =<span style="color: rgba(0, 0, 0, 1)"> base64.encodeToString(encrypted);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> base64Encrypted;
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
e.printStackTrace();
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AesException(AesException.EncryptAESError);
}
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 对密文进行解密.
*
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> text 需要解密的密文
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 解密得到的明文
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> AesException aes解密失败
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
String decrypt(String text) </span><span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> AesException {
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] original;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置解密模式为AES的CBC模式</span>
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"<span style="color: rgba(0, 0, 0, 1)">);
SecretKeySpec key_spec </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> SecretKeySpec(aesKey, "AES"<span style="color: rgba(0, 0, 0, 1)">);
IvParameterSpec iv </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16<span style="color: rgba(0, 0, 0, 1)">));
cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用BASE64对密文进行解码</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] encrypted =<span style="color: rgba(0, 0, 0, 1)"> Base64.decodeBase64(text);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 解密</span>
original =<span style="color: rgba(0, 0, 0, 1)"> cipher.doFinal(encrypted);
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
e.printStackTrace();
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AesException(AesException.DecryptAESError);
}
String xmlContent, from_appid;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 去除补位字符</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] bytes =<span style="color: rgba(0, 0, 0, 1)"> PKCS7Encoder.decode(original);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 分离16位随机字符串,网络字节序和AppId</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] networkOrder = Arrays.copyOfRange(bytes, 16, 20<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">int</span> xmlLength =<span style="color: rgba(0, 0, 0, 1)"> recoverNetworkBytesOrder(networkOrder);
xmlContent </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> String(Arrays.copyOfRange(bytes, 20, 20 +<span style="color: rgba(0, 0, 0, 1)"> xmlLength), CHARSET);
from_appid </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> String(Arrays.copyOfRange(bytes, 20 +<span style="color: rgba(0, 0, 0, 1)"> xmlLength, bytes.length),
CHARSET);
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
e.printStackTrace();
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AesException(AesException.IllegalBuffer);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> appid不相同的情况</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">from_appid.equals(appId)) {
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AesException(AesException.ValidateAppidError);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> xmlContent;
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 将公众平台回复用户的消息加密打包.
* <ol>
* <li>对要发送的消息进行AES-CBC加密</li>
* <li>生成安全签名</li>
* <li>将消息密文和安全签名打包成xml格式</li>
* </ol>
*
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> replyMsg 公众平台待回复用户的消息,xml格式的字符串
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> nonce 随机串,可以自己生成,也可以用URL参数的nonce
*
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> AesException 执行失败,请查看该异常的错误码和具体的错误信息
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> String encryptMsg(String replyMsg, String timeStamp, String nonce) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> AesException {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 加密</span>
String encrypt =<span style="color: rgba(0, 0, 0, 1)"> encrypt(getRandomStr(), replyMsg);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 生成安全签名</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (timeStamp == ""<span style="color: rgba(0, 0, 0, 1)">) {
timeStamp </span>=<span style="color: rgba(0, 0, 0, 1)"> Long.toString(System.currentTimeMillis());
}
String signature </span>=<span style="color: rgba(0, 0, 0, 1)"> SHA1.getSHA1(token, timeStamp, nonce, encrypt);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.out.println("发送给平台的签名是: " + signature.toString());
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 生成发送的xml</span>
String result =<span style="color: rgba(0, 0, 0, 1)"> XMLParse.generate(encrypt, signature, timeStamp, nonce);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 检验消息的真实性,并且获取解密后的明文.
* <ol>
* <li>利用收到的密文生成安全签名,进行签名验证</li>
* <li>若验证通过,则提取xml中的加密消息</li>
* <li>对消息进行解密</li>
* </ol>
*
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> msgSignature 签名串,对应URL参数的msg_signature
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> timeStamp 时间戳,对应URL参数的timestamp
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> nonce 随机串,对应URL参数的nonce
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> postData 密文,对应POST请求的数据
*
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 解密后的原文
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> AesException 执行失败,请查看该异常的错误码和具体的错误信息
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String decryptMsg(String msgSignature, String timeStamp, String nonce, String postData)
</span><span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> AesException {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 密钥,公众账号的app secret
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 提取密文</span>
Object[] encrypt =<span style="color: rgba(0, 0, 0, 1)"> XMLParse.extract(postData);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 验证安全签名</span>
String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt.toString());
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 和URL中的签名比较是否相等
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.out.println("第三方收到URL中的签名:" + msg_sign);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> System.out.println("第三方校验签名:" + signature);</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">signature.equals(msgSignature)) {
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AesException(AesException.ValidateSignatureError);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 解密</span>
String result = decrypt(encrypt.toString());
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 验证URL
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> msgSignature 签名串,对应URL参数的msg_signature
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> timeStamp 时间戳,对应URL参数的timestamp
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> nonce 随机串,对应URL参数的nonce
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> echoStr 随机串,对应URL参数的echostr
*
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 解密之后的echostr
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> AesException 执行失败,请查看该异常的错误码和具体的错误信息
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String verifyUrl(String msgSignature, String timeStamp, String nonce, String echoStr)
</span><span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> AesException {
String signature </span>=<span style="color: rgba(0, 0, 0, 1)"> SHA1.getSHA1(token, timeStamp, nonce, echoStr);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">signature.equals(msgSignature)) {
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AesException(AesException.ValidateSignatureError);
}
String result </span>=<span style="color: rgba(0, 0, 0, 1)"> decrypt(echoStr);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code"><img id="code_img_closed_ebab45dc-c785-4c61-b152-40c87713fa49" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_ebab45dc-c785-4c61-b152-40c87713fa49" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_ebab45dc-c785-4c61-b152-40c87713fa49" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ------------------------------------------------------------------------</span>
<span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext.wechat;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.w3c.dom.Document;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.w3c.dom.Element;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.w3c.dom.NodeList;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> org.xml.sax.InputSource;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> javax.xml.parsers.DocumentBuilder;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> javax.xml.parsers.DocumentBuilderFactory;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.io.StringReader;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* XMLParse class
*
* 提供提取消息格式中的密文及生成回复消息格式的接口.
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> XMLParse {
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 提取出xml数据包中的加密消息
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> xmltext 待提取的xml字符串
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 提取出的加密消息字符串
* </span><span style="color: rgba(128, 128, 128, 1)">@throws</span><span style="color: rgba(0, 128, 0, 1)"> com.qq.weixin.mp.aes.AesException
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> Object[] extract(String xmltext) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> AesException {
Object[] result </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Object;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
DocumentBuilderFactory dbf </span>=<span style="color: rgba(0, 0, 0, 1)"> DocumentBuilderFactory.newInstance();
dbf.setFeature(</span>"http://apache.org/xml/features/disallow-doctype-decl", <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
dbf.setFeature(</span>"http://xml.org/sax/features/external-general-entities", <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
dbf.setFeature(</span>"http://xml.org/sax/features/external-parameter-entities", <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
dbf.setFeature(</span>"http://apache.org/xml/features/nonvalidating/load-external-dtd", <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
dbf.setXIncludeAware(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
dbf.setExpandEntityReferences(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
DocumentBuilder db </span>=<span style="color: rgba(0, 0, 0, 1)"> dbf.newDocumentBuilder();
StringReader sr </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StringReader(xmltext);
InputSource is </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> InputSource(sr);
Document document </span>=<span style="color: rgba(0, 0, 0, 1)"> db.parse(is);
Element root </span>=<span style="color: rgba(0, 0, 0, 1)"> document.getDocumentElement();
NodeList nodelist1 </span>= root.getElementsByTagName("Encrypt"<span style="color: rgba(0, 0, 0, 1)">);
NodeList nodelist2 </span>= root.getElementsByTagName("ToUserName"<span style="color: rgba(0, 0, 0, 1)">);
result[</span>0] = 0<span style="color: rgba(0, 0, 0, 1)">;
result[</span>1] = nodelist1.item(0<span style="color: rgba(0, 0, 0, 1)">).getTextContent();
result[</span>2] = nodelist2.item(0<span style="color: rgba(0, 0, 0, 1)">).getTextContent();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
e.printStackTrace();
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AesException(AesException.ParseXmlError);
}
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 生成xml消息
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> encrypt 加密后的消息密文
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> signature 安全签名
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> timestamp 时间戳
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> nonce 随机字符串
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> 生成的xml字符串
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> String generate(String encrypt, String signature, String timestamp, String nonce) {
String format </span>= "<xml>\n" + "<Encrypt><!]></Encrypt>\n"
+ "<MsgSignature><!]></MsgSignature>\n"
+ "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><!]></Nonce>\n" + "</xml>"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> String.format(format, encrypt, signature, timestamp, nonce);
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code"><img id="code_img_closed_35562cb7-42e5-494d-bb7a-bcb54bacf450" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_35562cb7-42e5-494d-bb7a-bcb54bacf450" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_35562cb7-42e5-494d-bb7a-bcb54bacf450" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> webapp.ext;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.security.MessageDigest;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.security.NoSuchAlgorithmException;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.Arrays;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* @Author:Fei.chu
* @Date:Created in 21:52 2018/08/17
* @Description:微信签名校验
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> WechatSignUtil {
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 校验签名
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> signature 微信加密签名.
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> timestamp 时间戳.
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> nonce 随机数.
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span>
<span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)"> checkSignature(String signature, String timestamp, String nonce) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 对token、timestamp、和nonce按字典排序.</span>
String[] paramArr = <span style="color: rgba(0, 0, 255, 1)">new</span> String[] {"your token"<span style="color: rgba(0, 0, 0, 1)">, timestamp, nonce};
Arrays.sort(paramArr);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 将排序后的结果拼接成一个字符串.</span>
String content= paramArr.concat(paramArr).concat(paramArr);
String ciphertext </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
MessageDigest md </span>= MessageDigest.getInstance("SHA-1"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 对拼接后的字符串进行sha1加密.</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] digest =<span style="color: rgba(0, 0, 0, 1)"> md.digest(content.toString().getBytes());
ciphertext </span>=<span style="color: rgba(0, 0, 0, 1)"> byteToStr(digest);
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (NoSuchAlgorithmException e) {
e.printStackTrace();
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 将sha1加密后的字符串与signature进行对比.</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> ciphertext != <span style="color: rgba(0, 0, 255, 1)">null</span> ? ciphertext.equals(signature.toUpperCase()) : <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 将字节数组转换为十六进制字符串.
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> byteArray
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span>
<span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String byteToStr(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] byteArray) {
String strDigest </span>= ""<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < byteArray.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
strDigest </span>+=<span style="color: rgba(0, 0, 0, 1)"> byteToHexStr(byteArray);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> strDigest;
}
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 将字节转换为十六进制字符串.
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> mByte
* </span><span style="color: rgba(128, 128, 128, 1)">@return</span>
<span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String byteToHexStr(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)"> mByte) {
</span><span style="color: rgba(0, 0, 255, 1)">char</span>[] Digit = { '0', '1' , '2', '3', '4' , '5', '6', '7' , '8', '9', 'A' , 'B', 'C', 'D' , 'E', 'F'<span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 0, 255, 1)">char</span>[] tempArr = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">char</span>;
tempArr[</span>0] = Digit[(mByte >>> 4) & 0X0F<span style="color: rgba(0, 0, 0, 1)">];
tempArr[</span>1] = Digit;
String s </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> String(tempArr);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> s;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取token
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static String getToken() throws Exception{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String token = DbGhostApi.tokenIsValid();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> if (token != null) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> return token;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> } else {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Date now = new Date();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String rsp = HttpUtil.getString("</span><span style="color: rgba(0, 128, 0, 1); text-decoration: underline">https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential</span><span style="color: rgba(0, 128, 0, 1)">&appid=" + Config.appid + "&secret=" + Config.secret);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> JSONObject obj = JSONObject.parseObject(rsp);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String access_token = obj.getString("access_token");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> int expires_in = obj.getIntValue("expires_in");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> DbGhostApi.updateToken(access_token, DateUtil.dateAddSecond(now,expires_in));
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> return access_token;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> }
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> }</span>
}</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p><span style="color: rgba(255, 0, 0, 1)">注意:语音消息识别需要在公众号后台开启相应功能</span></p>
<p><img src="https://img2018.cnblogs.com/blog/1221763/201907/1221763-20190723132306040-1738972109.png" alt="" width="1183" height="483"></p><br><br>
来源:https://www.cnblogs.com/vicF/p/11230837.html
頁:
[1]