場景:團隊開放微信第三方公衆號,此公衆號中原先有一個活動,按照正常流程公衆號配置指定接收消息事件的url,服務器端指定servlet進行xml解析處理。java
如今原先基礎上增長一個活動,此時爲開放第三方公衆號,裏面有兩個活動暫且稱爲A和B,A原先由Fa服務器指定的servlet處理微信推過來的事件(好比說關注事件),A和B有不一樣的服務器,獨立的項目,不一樣的數據庫。此時需求是根據場景的不一樣,將微信推送過來的消息分別放在不一樣的servlet裏面進行解析處理。但實際上微信只往其中一個servlet中進行消息推送。web
過程:使用轉發就能夠不用考慮了,轉發只能在同一web中的servlet中進行跳轉。若是場景是在同一個tomcat中,那麼能夠用request.getRequestDispatcher("/xxxx").forward(request,response);數據庫
若是消息事件只涉及到消息推送等,也就是隻用到了微信推送xml裏面的數據,那麼上述場景徹底能夠在同一個servlet中進行處理,處理的方法就是根據不一樣的場景值。後端
具體的思路過程就不細說了,大致方向:在微信推送過來xml的時候就把xml給轉到指定的服務器下面的servlet中; 在進入到特定場景的時候把獲得的數據轉到知道的服務器下面的servlet中;api
結果:測試了各類方法百度了各類方法以後,我這裏用了java後端發送post請求:tomcat
這裏以微信第三方平臺開發爲例:服務器
微信推送過來的消息爲(部分代碼):微信
1 /** 2 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 3 * response) 4 */ 5 protected void doPost(HttpServletRequest request, HttpServletResponse response) 6 throws ServletException, IOException { 7 DebugUtils.savaDebugInfo(null, "進入到servlet種的dePost",null); 8 String nonce = request.getParameter("nonce"); 9 String timestamp = request.getParameter("timestamp"); 10 String msgSignature = request.getParameter("msg_signature"); 11 12 request.setCharacterEncoding("UTF-8"); 13 response.setCharacterEncoding("UTF-8"); 14 PrintWriter out = response.getWriter(); 15 String message = "success"; 16 try { 17 StringBuilder sb = new StringBuilder(); 18 BufferedReader in = request.getReader(); 19 String line; 20 while ((line = in.readLine()) != null) { 21 sb.append(line); 22 } 23 String xml = sb.toString();
收到消息後要對xml進行解析,微信官方文檔給的有解析的方法。解析以後根據解析出來的數據判斷不一樣的場景走不一樣的出來方法。app
如今我要在微信推送過來消息進入doPost方法的時候同時把消息發送到其餘指定的服務器下面servlet中去。ide
首先到指定服務器下,找到WEB-INF下面的xml文件進行servlet訪問配置:
1 <servlet> 2 <servlet-name>OpenWXMessageServlet</servlet-name> 3 <servlet-class> 4 xx.xx.xx.MessageServlet 5 </servlet-class> 6 </servlet> 7 <servlet-mapping> 8 <servlet-name>OpenWXMessageServlet</servlet-name> 9 <url-pattern>/OpenWXMessageServlet</url-pattern> 10 </servlet-mapping>
而後再接收到消息事件讀取到未解密的xml的時候去發送post請求:
1 /** 2 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 3 * response) 4 */ 5 protected void doPost(HttpServletRequest request, HttpServletResponse response) 6 throws ServletException, IOException { 7 DebugUtils.savaDebugInfo(null, "進入到servlet種的dePost",null); 8 String nonce = request.getParameter("nonce"); 9 String timestamp = request.getParameter("timestamp"); 10 String msgSignature = request.getParameter("msg_signature"); 11 12 request.setCharacterEncoding("UTF-8"); 13 response.setCharacterEncoding("UTF-8"); 14 PrintWriter out = response.getWriter(); 15 String message = "success"; 16 try { 17 StringBuilder sb = new StringBuilder(); 18 BufferedReader in = request.getReader(); 19 String line; 20 while ((line = in.readLine()) != null) { 21 sb.append(line); 22 } 23 String xml = sb.toString(); 24 String path = "http://xxxxxx.com/OpenWXMessageServlet?nonce=" 25 +nonce+"×tamp="+timestamp+"&msg_signature="+msgSignature; 26 String echostr = HttpRequest.sendPost(path, xml);
而後指定服務器接收到的時間戳和隨機數都是再一致狀態下的了。這樣就實現了開始場景的需求。
附帶一下我這邊的sendPost方法:
1 /** 2 * 向指定 URL 發送POST方法的請求 3 * 4 * @param url 5 * 發送請求的 URL 6 * @param param 7 * 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。 8 * @return 所表明遠程資源的響應結果 9 */ 10 public static String sendPost(String url, String param) { 11 return sendPost(url, param, ""); 12 } 13 public static String sendPost(String url, String param, String charset) { 14 PrintWriter out = null; 15 BufferedReader in = null; 16 String result = ""; 17 InterfaceInfo interfaceInfo = new InterfaceInfo(url, param, ""); 18 19 try { 20 URL realUrl = new URL(url); 21 // 打開和URL之間的鏈接 22 URLConnection conn = realUrl.openConnection(); 23 // 設置通用的請求屬性 24 conn.setConnectTimeout(60000); 25 conn.setReadTimeout(60000); 26 conn.setRequestProperty("accept", "application/Json;" + charset); 27 conn.setRequestProperty("connection", "Keep-Alive"); 28 conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 29 conn.setRequestProperty("Content-Type", "application/Json;charset=UTF-8;"); 30 // 地址接口用到x-auth-header 31 if (param.contains("AddressReq")) { 32 conn.setRequestProperty("X-AUTH-HEADER", "ACAE705AF0531007BDCBC29D5121DBD6"); 33 } 34 // 鉑濤錦江mpls通道必須加驗證 35 if(url.contains("/v1/score/pay")){ 36 conn.setRequestProperty("apigwkey", "d72fa68d5734bb66b4b27d9b5dd50f65"); 37 } 38 // 發送POST請求必須設置以下兩行 39 conn.setDoOutput(true); 40 conn.setDoInput(true); 41 // 獲取URLConnection對象對應的輸出流 42 out = new PrintWriter(conn.getOutputStream()); 43 // 發送請求參數 44 out.print(param); 45 // flush輸出流的緩衝 46 out.flush(); 47 // 定義BufferedReader輸入流來讀取URL的響應 48 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); 49 String line; 50 while ((line = in.readLine()) != null) { 51 result += line; 52 } 53 if (StringUtils.isBlank(result)) { 54 GetServiceUtil.getExceptionLogService().saveDebugInfo("扣分返回", "result等於空字符串"); 55 } 56 // 請求結束更新開始時保存的接口日誌 57 String resultInterface = ""; 58 if (result.length() > 1000) { 59 resultInterface = result.substring(0, 1000); 60 } else { 61 resultInterface = result; 62 } 63 interfaceInfo.setRESULT(resultInterface); 64 } catch (Exception e) { 65 interfaceInfo.setRESULT(e.getMessage()); 66 67 ExceptionLog exceptionLog = new ExceptionLog(); 68 exceptionLog.setExceptiontype(ConstantData.EXCEPTION_TYPE_RUNTIME); 69 exceptionLog.setExceptiontitle("Http異常"); 70 exceptionLog.setExceptionmsg(url); 71 if (e.toString().length() > 500) { 72 exceptionLog.setStack(e.toString().substring(0, 500)); 73 } else { 74 exceptionLog.setStack(e.toString()); 75 } 76 ExceptionServiceImpl exceptionService = GetServiceUtil.getExceptionService(); 77 exceptionService.insertExceptionLogInfo(exceptionLog); 78 79 if (e.toString().contains("401")) { 80 result = e.toString(); 81 } else { 82 result = "服務器異常。。"; 83 } 84 } 85 // 使用finally塊來關閉輸出流、輸入流 86 finally { 87 try { 88 GetServiceUtil.getExceptionLogService().saveInterfaceInfo(interfaceInfo); 89 if (out != null) { 90 out.close(); 91 } 92 if (in != null) { 93 in.close(); 94 } 95 } catch (IOException ex) { 96 ex.printStackTrace(); 97 } 98 } 99 return result; 100 }