zoukankan      html  css  js  c++  java
  • 微信消息接收事件-将微信接收消息转发到指定服务器的servlet处理

    场景:团队开放微信第三方公众号,此公众号中原先有一个活动,按照正常流程公众号配置指定接收消息事件的url,服务器端指定servlet进行xml解析处理。

        现在原先基础上增加一个活动,此时为开放第三方公众号,里面有两个活动暂且称为A和B,A原先由Fa服务器指定的servlet处理微信推过来的事件(比如说关注事件),A和B有不同的服务器,独立的项目,不同的数据库。此时需求是根据场景的不同,将微信推送过来的消息分别放在不同的servlet里面进行解析处理。但实际上微信只往其中一个servlet中进行消息推送。

    过程:使用转发就可以不用考虑了,转发只能在同一web中的servlet中进行跳转。如果场景是在同一个tomcat中,那么可以用request.getRequestDispatcher("/xxxx").forward(request,response);

       如果消息事件只涉及到消息推送等,也就是只用到了微信推送xml里面的数据,那么上述场景完全可以在同一个servlet中进行处理,处理的方法就是根据不同的场景值。

       具体的思路过程就不细说了,大体方向:在微信推送过来xml的时候就把xml给转到指定的服务器下面的servlet中;         在进入到特定场景的时候把得到的数据转到知道的服务器下面的servlet中;

    结果:测试了各种方法百度了各种方法之后,我这里用了java后端发送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();

      收到消息后要对xml进行解析,微信官方文档给的有解析的方法。解析之后根据解析出来的数据判断不同的场景走不同的出来方法。

      现在我要在微信推送过来消息进入doPost方法的时候同时把消息发送到其他指定的服务器下面servlet中去。

      首先到指定服务器下,找到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+"&timestamp="+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     }
    View Code
  • 相关阅读:
    LinkedList源码浅析
    ArrayList/Vector/Stack底层分析
    遮罩层
    重写alert方法,去掉地址显示
    继承属性的函数
    为什么手机网页点击输入框的瞬间会出现灰色背景呢?怎么去掉灰色背景?
    伪类before和after
    五星好评
    String[]字符串数组,按字典顺序排列大小
    jquery ajax的load()方法和load()事件
  • 原文地址:https://www.cnblogs.com/unidentified/p/10978448.html
Copyright © 2011-2022 走看看