夏日清荷 發表於 2019-7-23 11:39:00

微信公众号开发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>&lt;String,String&gt; map =<span style="color: rgba(0, 0, 0, 1)"> MessageUtil.xmlToMap(request);
                String xml </span>= "&lt;xml&gt;&lt;ToUserName&gt;"+map.get("ToUserName")+"&lt;/ToUserName&gt;&lt;Encrypt&gt;" +map.get("Encrypt")+
                        "&lt;/Encrypt&gt;&lt;/xml&gt;"<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>&lt;String, Object&gt; 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&lt;String, Object&gt; mapXml = <span style="color: rgba(0, 0, 255, 1)">new</span> HashMap&lt;&gt;<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&lt;String, Object&gt;<span style="color: rgba(0, 0, 0, 1)"> req,String receive) {
      HashMap</span>&lt;String, Object&gt; mapXml = <span style="color: rgba(0, 0, 255, 1)">new</span> HashMap&lt;&gt;<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>&nbsp;</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>&lt;Byte&gt; byteContainer = <span style="color: rgba(0, 0, 255, 1)">new</span> ArrayList&lt;Byte&gt;<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 &lt; 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&lt;String, String&gt; 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>&lt;String,String&gt; map = <span style="color: rgba(0, 0, 255, 1)">new</span> HashMap&lt;String, String&gt;<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>&lt;Element&gt; 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&lt;String,Object&gt;<span style="color: rgba(0, 0, 0, 1)"> xmlStr2Map(String xmlStr){
      Map</span>&lt;String,Object&gt; map = <span style="color: rgba(0, 0, 255, 1)">new</span> HashMap&lt;String,Object&gt;<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> &amp;&amp; children.size() &gt; 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 &lt; 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&lt;String,Object&gt;<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>"&lt;xml&gt;"<span style="color: rgba(0, 0, 0, 1)">);

      Set</span>&lt;String&gt; set =<span style="color: rgba(0, 0, 0, 1)"> map.keySet();
      </span><span style="color: rgba(0, 0, 255, 1)">for</span>(Iterator&lt;String&gt; 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>"&lt;").append(key).append("&gt;"<span style="color: rgba(0, 0, 0, 1)">);
            sb.append(value);
            sb.append(</span>"&lt;/").append(key).append("&gt;"<span style="color: rgba(0, 0, 0, 1)">);
      }
      sb.append(</span>"&lt;/xml&gt;"<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&lt;String,Object&gt;<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>"&lt;"+head+"&gt;"<span style="color: rgba(0, 0, 0, 1)">);
      }
      Set</span>&lt;String&gt; set =<span style="color: rgba(0, 0, 0, 1)"> map.keySet();
      </span><span style="color: rgba(0, 0, 255, 1)">for</span>(Iterator&lt;String&gt; 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>"&lt;").append(key).append("&gt;"<span style="color: rgba(0, 0, 0, 1)">);
            sb.append(value);
            sb.append(</span>"&lt;/").append(key).append("&gt;"<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>"&lt;/"+head+"&gt;"<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 &lt; 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 &lt; 1 || pad &gt; 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 &amp; 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 &lt; 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 &lt; digest.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
                shaHex </span>= Integer.toHexString(digest &amp; 0xFF<span style="color: rgba(0, 0, 0, 1)">);
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (shaHex.length() &lt; 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编码的字符串).
* &lt;ol&gt;
*   &lt;li&gt;第三方回复加密消息给公众平台&lt;/li&gt;
*   &lt;li&gt;第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。&lt;/li&gt;
* &lt;/ol&gt;
* 说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案
* &lt;ol&gt;
*   &lt;li&gt;在官方网站下载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)">&lt;/li&gt;
*   &lt;li&gt;下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt&lt;/li&gt;
*   &lt;li&gt;如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件&lt;/li&gt;
*   &lt;li&gt;如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件&lt;/li&gt;
* &lt;/ol&gt;
</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 &amp; 0xFF<span style="color: rgba(0, 0, 0, 1)">);
      orderBytes[</span>2] = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (sourceNumber &gt;&gt; 8 &amp; 0xFF<span style="color: rgba(0, 0, 0, 1)">);
      orderBytes[</span>1] = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (sourceNumber &gt;&gt; 16 &amp; 0xFF<span style="color: rgba(0, 0, 0, 1)">);
      orderBytes[</span>0] = (<span style="color: rgba(0, 0, 255, 1)">byte</span>) (sourceNumber &gt;&gt; 24 &amp; 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 &lt; 4; i++<span style="color: rgba(0, 0, 0, 1)">) {
            sourceNumber </span>&lt;&lt;= 8<span style="color: rgba(0, 0, 0, 1)">;
            sourceNumber </span>|= orderBytes &amp; 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 &lt; 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)">
   * 将公众平台回复用户的消息加密打包.
   * &lt;ol&gt;
   *   &lt;li&gt;对要发送的消息进行AES-CBC加密&lt;/li&gt;
   *   &lt;li&gt;生成安全签名&lt;/li&gt;
   *   &lt;li&gt;将消息密文和安全签名打包成xml格式&lt;/li&gt;
   * &lt;/ol&gt;
   *
   * </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)">
   * 检验消息的真实性,并且获取解密后的明文.
   * &lt;ol&gt;
   *   &lt;li&gt;利用收到的密文生成安全签名,进行签名验证&lt;/li&gt;
   *   &lt;li&gt;若验证通过,则提取xml中的加密消息&lt;/li&gt;
   *   &lt;li&gt;对消息进行解密&lt;/li&gt;
   * &lt;/ol&gt;
   *
   * </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>= "&lt;xml&gt;\n" + "&lt;Encrypt&gt;&lt;!]&gt;&lt;/Encrypt&gt;\n"
                + "&lt;MsgSignature&gt;&lt;!]&gt;&lt;/MsgSignature&gt;\n"
                + "&lt;TimeStamp&gt;%3$s&lt;/TimeStamp&gt;\n" + "&lt;Nonce&gt;&lt;!]&gt;&lt;/Nonce&gt;\n" + "&lt;/xml&gt;"<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 &lt; 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 &gt;&gt;&gt; 4) &amp; 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)">&amp;appid=" + Config.appid + "&amp;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>&nbsp;</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]
查看完整版本: 微信公众号开发java版-消息回复(普通文字消息和语音消息)