微信全網發佈監測,需要檢測的有以下幾項:
1、組件ticket正確接收;
2、生成預授權碼;
3、獲取授權code;
4、授權;
5、返回Api文本消息;
6、返回普通文本消息;
7、發送事件消息;
8、取消授權。
其中,1,2,3,4,8這幾項是授權的基本功能,基本上不會有人在這幾個地方出現問題。
而我們真正需要處理的,只有5,6,7這三項,這裏需要程序裏面添加額外的程序來處理。另外建議在程序裏面加上詳細的日誌,將微信發送過來的數據,和我們向他發送消息的返回值詳細的記錄下來,以便調試程序。
AesException
補上,有的人可能會報AesException,這是因爲用到了jdk sercurity, 而jdk sercurity 使用的jar包 $JAVA_HOME/lib/security/local_policy.jar 和 $JAVA_HOME/jre6_64/lib/security/US_export_policy.jar中有對技術出口的限制,加密只有128bit,而沒有限制的則有256bit.
解決辦法:
1. 按照版本選擇下載 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8
2. 下載jce_policy-1_8_2.zip後解壓,放入$JAVA_HOME/lib/security/目錄下替換原來的jar包。
返回Api文本消息
微信會向我們推送一個文本消息過來(消息需要解密),這裏需要我們將它推送過來的消息裏面的query_auth_code提取出來,作爲authorization_code調用“使用授權碼換取公衆號的授權信息”接口去獲取操作測試微信賬號所需要的authorizer_access_token。獲取到token之後,就可以調用發送客服消息api向騰訊發送文本消息。
消息的格式:
{
"touser":"OPENID",
"msgtype":"text",
"text":
{
"content":"Hello World"
}
}
content就是剛剛從消息裏面提取出來的query_auth_code+"from_api",touser的值openid是從剛剛接收到的消息裏面獲取到的發送人的id。這裏,官方文檔上面有說明收到消息的時候先回復一個空字符串,但是實際上這裏是可以不回覆的,只要在5秒只內完成api消息回覆。另外,還要注意非常重要的一點,發送過去的api文本消息是不需要加密的,微信的文檔上這個地方沒有說清楚(如果發送客服消息微信返回40003,檢查一下這裏是否加密了,把加密去掉)。
返回普通文本消息
這個地方很簡單,微信會向我們推送一個文本消息過來(消息需要解密),內容是TESTCOMPONENT_MSG_TYPE_TEXT,這是固定值,不是變量,我們收到消息消息之後,(Java)直接調用response回覆一條消息給他,注意消息的格式是被動回覆用戶消息,跟上面那個不一樣。
消息的格式:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[TESTCOMPONENT_MSG_TYPE_TEXT_callback]]></Content>
</xml>
返回事件消息
微信會向我們推送一個消息過來(消息需要解密),這裏的處理和返回普通文本消息類似,收到微信推送過來的事件消息之後,用response回覆一條消息,消息的格式同上,內容爲even+"from_callback",實際測試even的值固定是location(估計是他們那邊的人偷懶),所以這裏回覆它的消息內容可以固定爲LOCATIONfrom_callback。這裏回覆的消息也是需要加密的。
如果有朋友對這裏或者授權開發的有疑問,或者對源碼有需要,請留言!
成功截圖
其中content值爲TESTCOMPONENT_MSG_TYPE_TEXT_callback固定值。這裏返回的普通文本消息是需要解密的。
返回事件消息
微信會向我們推送一個消息過來(消息需要解密),這裏的處理和返回普通文本消息類似,收到微信推送過來的事件消息之後,用response回覆一條消息,消息的格式同上,內容爲even+"from_callback",實際測試even的值固定是location(估計是他們那邊的人偷懶),所以這裏回覆它的消息內容可以固定爲LOCATIONfrom_callback。這裏回覆的消息也是需要加密的。
如果有朋友對這裏或者授權開發的有疑問,或者對源碼有需要,請留言!
成功截圖
以下是部分源碼(步驟1的源碼沒在其中,這個地方因爲不會有人出問題,所以就懶得貼了):
public class WechatPublishCheck {
public static void check(HttpServletRequest request, HttpServletResponse response) {
String msgSignature = request.getParameter("msg_signature");
String timeStamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String sendToWechatStr = "";
LIVE800LOGGER.logDebug("進入微信全網發佈測試");
Map < String,
String > requestMap = null;
String postDataXml = null;
try {
postDataXml = StringUtil.dealWithInputStream(request.getInputStream());
LIVE800LOGGER.logDebug("解密之前的postDataXml=" + postDataXml);
postDataXml = WechatComponentInfo.getWXBizMsgCrypt().decryptMsg2(msgSignature, timeStamp, nonce, postDataXml);
LIVE800LOGGER.logDebug("解密之後的postDataXml=" + postDataXml);
} catch(AesException e) {
LIVE800LOGGER.logError("解密微信推送的消息出錯", e);
return;
} catch(Exception e) {
LIVE800LOGGER.logError("處理inputstream出錯", e);
return;
}
try {
requestMap = MsgConverterUtil.parseXml(postDataXml);
LIVE800LOGGER.logDebug("requestMap=" + requestMap.toString());
} catch(MsgConvertException e) {
LIVE800LOGGER.logError("----------------", e);
return;
} catch(DocumentException e) {
LIVE800LOGGER.logError("----------------", e);
return;
} catch(IOException e) {
LIVE800LOGGER.logError("----------------", e);
return;
}
//響應事件推送消息
String msgType = requestMap.get("MsgType").toString();
LIVE800LOGGER.logDebug("msgType=" + msgType);
if (msgType.contains("event") || requestMap.containsKey("Event")) {
LIVE800LOGGER.logDebug("進入響應事件推送消息!");
String event = requestMap.get("Event").toString();
StringBuilder sendToWechatXml = new StringBuilder(); //構造回覆的字符串
sendToWechatXml.append("<xml>");
sendToWechatXml.append("<ToUserName><![CDATA[" + requestMap.get("FromUserName").toString() + "]]></ToUserName>");
sendToWechatXml.append("<FromUserName><![CDATA[" + requestMap.get("ToUserName").toString() + "]]></FromUserName>");
sendToWechatXml.append("<CreateTime>" + System.currentTimeMillis() + "</CreateTime>");
sendToWechatXml.append("<MsgType><![CDATA[text]]></MsgType>");
sendToWechatXml.append("<Content><![CDATA[" + event + "from_callback]]></Content>");
sendToWechatXml.append("</xml>");
LIVE800LOGGER.logDebug("準備響應微信事件的加密之前的文本消息=" + sendToWechatXml.toString());
try {
sendToWechatStr = WechatComponentInfo.getWXBizMsgCrypt().encryptMsg(sendToWechatXml.toString(), timeStamp, nonce);
LIVE800LOGGER.logDebug("準備響應微信事件的加密之後的文本消息=" + sendToWechatStr);
try {
response.getWriter().write(sendToWechatStr);
return;
} catch(IOException e) {
LIVE800LOGGER.logError("----------------", e);
return;
}
} catch(AesException e) {
LIVE800LOGGER.logError("加密微信發送的消息出錯", e);
return;
}
}
//回覆文本消息
try {
if (requestMap != null && requestMap.get("Content") != null && requestMap.get("Content").toString().equals("TESTCOMPONENT_MSG_TYPE_TEXT")) {
LIVE800LOGGER.logDebug("開始回覆文本消息!");
StringBuilder sendToWechatXml = new StringBuilder(); //構造回覆的字符串
sendToWechatXml.append("<xml>");
sendToWechatXml.append("<ToUserName><![CDATA[" + requestMap.get("FromUserName").toString() + "]]></ToUserName>");
sendToWechatXml.append("<FromUserName><![CDATA[" + requestMap.get("ToUserName").toString() + "]]></FromUserName>");
sendToWechatXml.append("<CreateTime>" + System.currentTimeMillis() + "</CreateTime>");
sendToWechatXml.append("<MsgType><![CDATA[text]]></MsgType>");
sendToWechatXml.append("<Content><![CDATA[TESTCOMPONENT_MSG_TYPE_TEXT_callback]]></Content>");
sendToWechatXml.append("</xml>");
LIVE800LOGGER.logDebug("準備響應微信的加密之前的文本消息=" + sendToWechatXml.toString());
try {
sendToWechatStr = WechatComponentInfo.getWXBizMsgCrypt().encryptMsg(sendToWechatXml.toString(), timeStamp, nonce);
LIVE800LOGGER.logDebug("準備響應微信的加密之後的文本消息=" + sendToWechatStr);
response.getWriter().write(sendToWechatStr);
return;
} catch(AesException e) {
LIVE800LOGGER.logError("加密微信發送的消息出錯", e);
return;
}
}
} catch(IOException e) {
LIVE800LOGGER.logError("response error,TESTCOMPONENT_MSG_TYPE_TEXT_callback,uri:");
return;
}
//調用微信api回覆文本消息
LIVE800LOGGER.logDebug("開始調用微信api回覆文本消息!");
String queryAuthCode = requestMap.get("Content").toString();
if (queryAuthCode.startsWith("QUERY_AUTH_CODE")) {
try {
PrintWriter printWriter = response.getWriter();
printWriter.write("");
printWriter.flush();
} catch(IOException e) {
LIVE800LOGGER.logDebug("發送空字符串失敗!");
return;
}
LIVE800LOGGER.logDebug("獲取到推送的queryAuthCode=" + queryAuthCode);
String authion_code = queryAuthCode.split(":")[1];
StringBuilder sendToWechatJson = new StringBuilder("{");
sendToWechatJson.append("\"touser\":\"" + requestMap.get("FromUserName").toString() + "\",");
sendToWechatJson.append("\"msgtype\":\"text\",");
sendToWechatJson.append("\"text\":{\"content\":\"" + authion_code + "_from_api\"}");
sendToWechatJson.append("}");
WechatAuthorizerAccessToken authorizerAccessToken = new WechatAuthorizerAccessToken();
authorizerAccessToken.setAuthorizationCode(authion_code);
LIVE800LOGGER.logDebug("獲取到的授權的測試公衆號的token=" + authorizerAccessToken.getToken());
LIVE800LOGGER.logDebug("調用微信客服消息發送接口,發送過去的消息爲:sendToWechatJson=" + sendToWechatJson.toString());
MsgSendResult msgSendResult = WechatServerAccessor.sendMsg(authorizerAccessToken, sendToWechatJson.toString());
LIVE800LOGGER.logDebug("發送微信的api消息,發送結果:result=" + msgSendResult.getResult() + ",reponseContent" + msgSendResult.getReponseContent());
return;
}
}
轉自: http://blog.csdn.net/dk947960731/article/details/52204408