转自: http://www.cuiyongzhi.com/post/39.html

在上一篇的文章中我们详细讲述了如何将我们的应用服务器和微信腾讯服务器之间的对接操作,最后接入成功,不知道你有没有发现在上一篇的【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】,截图大致如下:

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

Java微信公众平台开发(二)--微信服务器post消息体的接收的更多相关文章

  1. php 微信公众平台开发之微信群发信息

    这篇文章主要为大家详细介绍了php微信公众平台开发之微信群发信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.目的 完成在微信公众号中群发消息.这里只是完成简单的文字发送.也可以发送语音图片 ...

  2. Java微信公众平台开发(十)--微信用户信息的获取

    前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信用户的信息,在上一篇我们有说道微信用户和微信公众账号之间的联系可以通过Openid关 ...

  3. 微信公众平台开发(110) 微信连Wi-Fi

    关键字:微信公众平台 微信连Wi-Fi 微信 WiFi 硬件鉴权作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/p/weixin-wifi.html 微信连Wi- ...

  4. 基于PHP的微信公众平台开发(TOKEN验证,消息回复)

    微信公众平台开发 实现步骤: 第一步:填写服务器配置 登录微信公众平台官网后,在公众平台后台管理页面 - 开发者中心页,点击“修改配置”按钮,填写服务器地址(URL).Token和EncodingAE ...

  5. C# 微信公众平台开发(4)-- 模版消息

    微信公众平台开发 --发送模版消息 发送模版消息是微信服务号给某个用户发送模版消息,类似于APP的推送通知: 1.添加模版消息 在页面的左上 有一个添加功能插件的 按钮,如题 添加完成后,我们就可以在 ...

  6. Java微信公众平台开发(十)--微信自定义菜单的创建实现

    转自:http://www.cuiyongzhi.com/post/48.html 自定义菜单这个功能在我们普通的编辑模式下是可以直接在后台编辑的,但是一旦我们进入开发模式之后我们的自定义菜单就需要自 ...

  7. Java微信公众平台开发(六)--微信开发中的token获取

    转自:http://www.cuiyongzhi.com/post/44.html (一)token的介绍 引用:access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access ...

  8. Java微信公众平台开发(十三)--微信JSSDK中Config配置

    转自:http://www.cuiyongzhi.com/post/57.html 前端开发工程师和关注前端开发的开发者们在2015年中肯定被腾讯的JSSDk引爆过,搞APP的.搞前端的甚至是是搞后端 ...

  9. Java微信公众平台开发_05_微信网页授权

    GitHub源码:https://github.com/shirayner/weixin_gz 一.本节要点 1.网页授权回调域名 登录微信公众平台后台, 开发 - 接口权限 - 网页服务 - 网页帐 ...

随机推荐

  1. jQuery 图片自动播放

    var imgArray = new Array("images/1.jpg", "images/2.jpg","images/3.jpg" ...

  2. Centos6.8 JDK配置

    记录一下在这个服务器配置的过程 ssh root@IP Password --------------------------------------------------------------- ...

  3. Puzzle Game HihoCoder - 1634

    题目链接:https://cn.vjudge.net/problem/HihoCoder-1634 题目意思:可以让矩阵里的某一个数变成p,或者不修改.求最大子矩阵最小,输出最小值. 思路:请看下图 ...

  4. android安装apk

     * 安装apk */ private void installApk() { // 获取当前sdcard存储路径 File apkfile = new File(Environment.getE ...

  5. 专业工具软件PCB板打印说明

    专业工具软件PCB板打印说明 请注意PCB板打印不要直接截图,如下方式是不正确的: 这样在打印为黑白图片时,元器件之间的连线无法看清. 应采用如下模式: ~End~

  6. canvas 创建渐变图形

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. Golang Printf、Sprintf 、Fprintf 格式化

    /* %v 输出结构体 {10 30} %+v 输出结构体显示字段名 {one:10 tow:30} %#v 输出结构体源代码片段 main.Point{one:10, tow:30} %T 输出值的 ...

  8. UART驱动分析

    在linux用户层上要操作底层串口需要对/dev/ttySxxx操作,这里的ttySx指实际的终端串口. 以下以全志A64为实例,分析UART驱动以及浅谈TTY架构. linux-3.10/drive ...

  9. Vant async-validator 表单校验

    感谢:尤大大的 vue.有赞的 vant.async-validator.以及 asseek 链接:https://www.jianshu.com/p/d58fe749b97f 在下不才在 assee ...

  10. C#防止程序多次运行

    经过我的测试,还比较好用,但是有个问题,如果不注销,用另一个用户进入,则程序不能判断出已运行.所以只限于用在单用户环境,还是不太完美. class Program { [STAThread] stat ...