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

转自: 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,并没有对消息做出来,那么下一篇我们将讲述对消息的分类处理!感谢你的翻阅,如有疑问可以留言讨论!

原文地址:https://www.cnblogs.com/sharpest/p/10231262.html

时间: 2024-10-05 20:54:53

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

微信公众平台开发(102) 微信支付账号体系

本文介绍微信支付账号体系各参数. 商户在微信公众平台提交申请资料以及银行账户资料,资料审核通过并签约后,可以获得表6-4所示帐户(包含财付通的相关支付资金账户),用于公众帐号支付. 帐号 作用 appId 公众帐号身份的唯一标识.审核通过后,在微信发送的邮件中查看. appSecret 公众帐号支付请求中用于加密的密钥Key,可验证商户唯一身份,PaySignKey对应于支付场景中的appKey值.审核通过后,在微信发送的邮件中查看. paySignKey 除了支付请求需要用到paySignKe

微信公众平台开发(101) 微信支付URL配置

本文介绍微信支付申请时如何设置授权目录及URL. 一.选择支付类型 目前有两种支付类型 JS API网页支付 Native原生支付 如果没有特殊要求,两种都勾选. 二.支付授权目录 目前可以选择http还是https协议,没有特别要求,选择http.对安全要求比较高的企业,请选择https. 支付授权目录填写自己公司的域名加上目录,目录可以是不存在的目录,例如wxpay. 一个完整的目录参考如下: http://www.doucube.com/wxpay/ 蓝色部分表示要选择的. 红色部分表示要

【微信公众平台开发】微信刮刮乐,解决三星兼容性问题

刮刮乐jquery插件:wScratchPad 完整项目资源下载:点击打开链接 运用wScratchPad插件很快弄出刮刮乐的效果,代码如下: <!DOCTYPE html> <html> <head> <meta CHARSET="UTF-8"> <title>刮刮乐</title> <script type="text/javascript" src="./inc/jquer

【微信公众平台开发】微信幸运大转盘

需要js插件(下载包地址:http://download.csdn.net/detail/wyz365889/7798255): jquery jQueryRotate.2.2.js jquery.easing.min.js 前端显示代码: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name=

微信公众平台开发(121) 微信二维码海报

关键字:微信公众平台 二维码 海报作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/weixin-poster.html 本文介绍微信公众平台下二维码海报的开发过程. 一.微信二维码海报介绍 微信二维码海报是指在海报中嵌入和微信用户关联的参数二维码的海报,用户分享推广之后,新用户可以被统计为被推广人员数,从而达到增加粉丝的传播效果.其使用场景如下:   二.开发流程 在微信二维码海报生成中,需要用到以下信息 1. 自定义菜单中设置一个菜单项,点击后返回二维

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

关键字:微信公众平台 微信连Wi-Fi 微信 WiFi 硬件鉴权作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/p/weixin-wifi.html 微信连Wi-Fi是为商家的线下场所提供一套完整和便捷的微信连Wi-Fi的方案.商家接入微信连Wi-Fi后,顾客无需输入繁琐的Wi-Fi密码,通过微信扫二维码等方式即可快速上网.微信连Wi-Fi还帮助商家打造个性化服务,如提供微信顶部常驻入口.商家主页展示.连网后公众号下发消息等.因此,微信连Wi-Fi既可以极大

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

微信公众平台开发 --发送模版消息 发送模版消息是微信服务号给某个用户发送模版消息,类似于APP的推送通知: 1.添加模版消息 在页面的左上 有一个添加功能插件的 按钮,如题 添加完成后,我们就可以在左边的菜单栏看到 相应的信息了: 2.添加模版消息    详情里面有关模版的介绍,和发送短信需要传送的数据: 3.发送模版消息 接口调用请求说明http请求方式: POST https://api.weixin.qq.com/cgi-bin/message/template/send?access_

微信公众平台开发-- 关闭微信浏览器

在这篇微信公众平台开发教程中,我们将介绍如何使用微信JS接口关闭微信内置浏览器返回到微信聊天窗口界面. 微信的JS接口目前已公布了三种:右上角按钮/底部导航栏/用户网络状态,另外转发到朋友圈和分享到好友也可以使用JS接口来定义. 而关闭微信浏览器可以使用 WeixinJSBridge.call('closeWindow');" 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 2 &l

微信公众平台开发[2] —— 微信端分享功能

初次尝试微信公众号的开发,对于学习方法的探索都是来源于网上的博客.问答,对于参差不齐的信息,自己也是有苦说不出,抽出一点时间写点文章,既是对自己的学习总结,也希望给予同是菜鸟的学渣一点帮助.-- 前言. 背景介绍: 今天想添加微信分享的功能,如果不进行自定义设计,那么当我们点击分享朋友圈.好友或者QQ好友.空间时,默认的标题就是<title>标签中的信息,而显示的描述信息就是链接,图片多是默认为页面中显示的第一张图片,显然这样的处理是不合理的,所以需要查询开发文档进行编码设计. 操作步骤: 一