1. 程式人生 > >微信被動回覆訊息失敗所有的坑!Java篇【避坑指南】

微信被動回覆訊息失敗所有的坑!Java篇【避坑指南】

背景:

隨便一個微信訂閱號都可以,使用者在訂閱號傳送訊息,然後我們自己的伺服器做出訊息回覆,之間的過程處理好多坑。

我這裡是從接入成功後開始踩到的坑,關於接入的沒什麼,微信公眾號文件很清楚。

開始了:

我的伺服器使用的ssm框架

1.坑列表:

  1. 獲取微信請求我方伺服器引數的坑
  2. 響應訊息xml的坑
  3. 響應訊息引數的坑

一個個解決:

我的控制器程式碼,沒有驗證是否來自微信,接入的時候自己加(注意我接收到的引數和返回時的引數,尤其是接收人和傳送人

@RequestMapping(value = "toMsg",method = RequestMethod.POST,produces = {"application/xml; charset=UTF-8"})
    public void toMsg(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("微信返回了--------Weichart_Return");
        String resXml="";
        InputStream inputStream ;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String reqXmlStr;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((reqXmlStr = in.readLine()) != null){
            sb.append(reqXmlStr);
        }
        in.close();
        inputStream.close();
        System.out.println(sb.toString());
        try {
            Map<String, Object> map = XMLUtil.xmlStrToMap(sb.toString());
            String toUserName = map.get("ToUserName").toString();//開發者微訊號
            String fromUserName = map.get("FromUserName").toString();//傳送方帳號(一個OpenID)
            String createTime = map.get("CreateTime").toString();//訊息建立時間 (整型)
            String msgType = map.get("MsgType").toString();//訊息型別
            String content = map.get("Content").toString();//訊息內容
            String msgId = map.get("MsgId").toString();//訊息id,64位整型
            log.info("接收到的訊息:\r\n"+"ToUserName="+toUserName+"\r\nFromUserName="+fromUserName+"\r\nCreateTime="+
                    createTime+"\r\nMsgType="+msgType+"\r\nContent="+content+"\r\nMsgId="+msgId);
            String resXmlStr="<xml><ToUserName><![CDATA["+fromUserName+"]]></ToUserName>" +//此處要填寫 傳送方帳號(一個OpenID)
                    "<FromUserName><![CDATA["+toUserName+"]]></FromUserName>" +//此處填寫開發者微訊號
                    "<CreateTime>"+createTime+"</CreateTime>" +
                    "<MsgType><![CDATA["+msgType+"]]></MsgType>"+
                    "<Content><![CDATA["+content+"]]></Content></xml>";
            log.info(resXmlStr);
            response.getWriter().print(resXmlStr);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

1.接收微信引數,要從request的請求流InputStream中取出,然後再轉換為你自己需要的資料型別,此處我轉換為Map型別了,使用的dom4j把字串轉為dom物件然後存入Map的

2.返回XML的時候有幾點要注意:

(1)使用流返回,response的getWriter().print(xmlStr);返回,不要使用return String;的方式返回,容易攜帶些不知名資訊。

(2)返回的XML資料格式一定要正確,尤其是<![CDATA  和 ]]>  這不是多個符號,而是兩個符號,所以中間不要有空格,不然你是無法把字串轉XML的,返回的時候也會報錯

(3)引數問題,仔細看文件,接收訊息和被動回覆訊息的時候,其實ToUserName和FromUserName兩個引數其實是反的,也就是說傳送人和接收人是反的

,這個要注意,其實仔細看官網文件引數說明就能避免。

(4)spring mvc的資料返回型別,一般在mvc配置檔案中配置返回的是json格式,此處要單獨設定為返回型別是xml格式,也就是在@RequestMapping註解的produces屬性中設定返回型別和編碼格式,如果不配置返回xml格式的話返回的所有都正確,但是在xml的前後各加了個引號(這就是json的格式,String型別要加引號),微信就不認了

@RequestMapping(value = "toMsg",method = RequestMethod.POST,produces = {"application/xml; charset=UTF-8"})

只要注意這些坑注意了,那麼被動回覆就會成功,沒有問題的。

如果還沒有成功的話,那就去看看微信公眾號的運維中心看看日誌吧,然後根據日誌再做處理(注:日誌有延時,時間還比較長)

自動回覆成功圖:

我的已經解決了,如果還有沒提到的坑,請留言,我會回覆的