Java微信公众平台开发(二)——微信服务器post消息体的接收

在上一篇的文章中我们详细讲述了如何将我们的应用服务器和微信腾讯服务器之间的对接操作,最后接入成功,不知道你有没有发现在上一篇的【controller】中我定义了一个get方法和一个post方法,但是在使用过程中我们就用了get方法,这里我们就来说说我们预留的post的方法的使用!

当我们在完成了服务器验证之后,此后用户每次向公众号发送消息、或者产生自定义菜单点击事件时,开发者填写的服务器配置URL将得到微信服务器推送过来的消息和事件,然后开发者可以依据自身业务逻辑进行响应,例如回复消息等!通过这句话我们能知道后面所有的微信服务器和我们应用服务器之间的沟通都是通过post消息体来完成的,那么我们这里将讲述如何接受微信post的消息体!

(一)消息类型和消息格式

上面有说道我们所有的和微信服务器之间进行沟通基本都是通过post消息体完成的,首先我们了解下消息体的类型,大致类型有两种:

  • 普通消息类型:文本消息、图片消息、语音消息、视频消息、小视频消息、地理位置消息、链接消息

  • 事件消息类型:关注/取消关注事件、扫描带参数二维码事件、上报地理位置事件、自定义菜单事件、点击菜单拉取消息时的事件推送、点击菜单跳转链接时的事件推送

消息类型:微信服务端推送的所有消息体的类型格式都是xml格式;

(二)消息重试机制

微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试,但是这里后期可以使用【客服消息接口】去完成消息再次推送。

(三)消息接收处理

在前面我们有说道微信的消息体是采用xml格式,那么我在这里写了一个MessageUtil去做消息格式的处理,大致代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package  com.cuiyongzhi.wechat.util;
import  java.io.InputStream;
import  java.io.Writer;
import  java.util.HashMap;
import  java.util.List;
import  java.util.Map;
 
import  javax.servlet.http.HttpServletRequest;
 
import  org.dom4j.Document;
import  org.dom4j.Element;
import  org.dom4j.io.SAXReader;
 
import  com.thoughtworks.xstream.XStream;
import  com.thoughtworks.xstream.core.util.QuickWriter;
import  com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import  com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import  com.thoughtworks.xstream.io.xml.XppDriver;
   
/**
  * ClassName: MessageUtil
  * @Description: 消息工具类
  * @author dapengniao
  * @date 2016年3月7日 上午10:05:04
  */
public  class  MessageUtil {  
   
     /** 
      * 返回消息类型:文本 
      */  
     public  static  final  String RESP_MESSAGE_TYPE_TEXT =  "text" ;  
   
     /** 
      * 返回消息类型:音乐 
      */  
     public  static  final  String RESP_MESSAGE_TYPE_MUSIC =  "music" ;  
   
     /** 
      * 返回消息类型:图文 
      */  
     public  static  final  String RESP_MESSAGE_TYPE_NEWS =  "news" ;  
   
     /** 
      * 请求消息类型:文本 
      */  
     public  static  final  String REQ_MESSAGE_TYPE_TEXT =  "text" ;  
   
     /** 
      * 请求消息类型:图片 
      */  
     public  static  final  String REQ_MESSAGE_TYPE_IMAGE =  "image" ;  
   
     /** 
      * 请求消息类型:链接 
      */  
     public  static  final  String REQ_MESSAGE_TYPE_LINK =  "link" ;  
   
     /** 
      * 请求消息类型:地理位置 
      */  
     public  static  final  String REQ_MESSAGE_TYPE_LOCATION =  "location" ;  
   
     /** 
      * 请求消息类型:音频 
      */  
     public  static  final  String REQ_MESSAGE_TYPE_VOICE =  "voice" ;  
   
     /** 
      * 请求消息类型:推送 
      */  
     public  static  final  String REQ_MESSAGE_TYPE_EVENT =  "event" ;  
   
     /** 
      * 事件类型:subscribe(订阅) 
      */  
     public  static  final  String EVENT_TYPE_SUBSCRIBE =  "subscribe" ;  
   
     /** 
      * 事件类型:unsubscribe(取消订阅) 
      */  
     public  static  final  String EVENT_TYPE_UNSUBSCRIBE =  "unsubscribe" ;  
   
     /** 
      * 事件类型:CLICK(自定义菜单点击事件) 
      */  
     public  static  final  String EVENT_TYPE_CLICK =  "CLICK" ;  
   
     /**
      * @Description: 解析微信发来的请求(XML) 
      * @param @param request
      * @param @return
      * @param @throws Exception   
      * @author dapengniao
      * @date 2016年3月7日 上午10:04:02
      */
     @SuppressWarnings ( "unchecked" )
     public  static  Map<String, String> parseXml(HttpServletRequest request)  throws  Exception {  
         // 将解析结果存储在HashMap中   
         Map<String, String> map =  new  HashMap<String, String>();  
   
         // 从request中取得输入流   
         InputStream inputStream = request.getInputStream();  
         // 读取输入流   
         SAXReader reader =  new  SAXReader();  
         Document document = reader.read(inputStream);  
         // 得到xml根元素   
         Element root = document.getRootElement();  
         // 得到根元素的所有子节点   
         List<Element> elementList = root.elements();  
   
         // 遍历所有子节点   
         for  (Element e : elementList)  
             map.put(e.getName(), e.getText());  
   
         // 释放资源   
         inputStream.close();  
         inputStream =  null ;  
   
         return  map;  
     }  
   
     @SuppressWarnings ( "unused" )
     private  static  XStream xstream =  new  XStream( new  XppDriver() {  
         public  HierarchicalStreamWriter createWriter(Writer out) {  
             return  new  PrettyPrintWriter(out) {  
                 // 对所有xml节点的转换都增加CDATA标记   
                 boolean  cdata =  true ;  
                 @SuppressWarnings ( "rawtypes" )
                 public  void  startNode(String name, Class clazz) {  
                     super .startNode(name, clazz);  
                 }  
   
                 protected  void  writeText(QuickWriter writer, String text) {  
                     if  (cdata) {  
                         writer.write( "<![CDATA[" );  
                         writer.write(text);  
                         writer.write( "]]>" );  
                     else  {  
                         writer.write(text);  
                     }  
                 }  
             };  
         }  
     });  
}

在这个方法体里需要用到部分依赖,需要在pom文件加入如下部分:

1
2
3
4
5
6
7
8
9
10
11
12
<!-- xml -->
< dependency >
     < groupId >org.apache.directory.studio</ groupId >
     < artifactId >org.dom4j.dom4j</ artifactId >
     < version >1.6.1</ version >
</ dependency >
 
< dependency >
     < groupId >com.thoughtworks.xstream</ groupId >
     < artifactId >xstream</ artifactId >
     < version >1.4.8</ version >
</ dependency >

然后将我们的WechatSecurity Controller中的post方法修改为如下,用于做消息的接收和处理:

1
2
3
4
5
6
7
8
9
10
11
@RequestMapping (value =  "security" , method = RequestMethod.POST)
     // post方法用于接收微信服务端消息
     public  void  DoPost(HttpServletRequest request,HttpServletResponse response) {
         System.out.println( "这是post方法!" );
         try {
         Map<String, String> map=MessageUtil.parseXml(request);
         System.out.println( "=============================" +map.get( "Content" ));
         } catch (Exception e){
             logger.error(e,e);
         }
     }

因为前面我们已经开启了我们的开发者模式,那么当我们在这里将我们代码发布之后再公众号上发送消息,在们的后台就能看到我们的消息体进入并解析成功了,这里我输出的是微信的【原始ID】,截图大致如下:

1.jpg在这里我只是做了消息体的接收和转换成Map,并没有对消息做出来,那么下一篇我们将讲述对消息的分类处理!感谢你的翻阅,如有疑问可以留言讨论!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值