用户请求消息的封装和解析

一.请求消息的封装

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

各消息类型的推送XML数据包结构如下:

文本消息

<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[this is a test]]></Content>
 <MsgId>1234567890123456</MsgId>
 </xml>
参数描述
ToUserName开发者微信号
FromUserName发送方帐号(一个OpenID)
CreateTime消息创建时间 (整型)
MsgTypetext
Content文本消息内容
MsgId消息id,64位整型

图片消息

<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[image]]></MsgType>
 <PicUrl><![CDATA[this is a url]]></PicUrl>
 <MediaId><![CDATA[media_id]]></MediaId>
 <MsgId>1234567890123456</MsgId>
 </xml>
参数描述
ToUserName开发者微信号
FromUserName发送方帐号(一个OpenID)
CreateTime消息创建时间 (整型)
MsgTypeimage
PicUrl图片链接(由系统生成)
MediaId图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
MsgId消息id,64位整型

语音消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<Format><![CDATA[Format]]></Format>
<MsgId>1234567890123456</MsgId>
</xml>
参数描述
ToUserName开发者微信号
FromUserName发送方帐号(一个OpenID)
CreateTime消息创建时间 (整型)
MsgType语音为voice
MediaId语音消息媒体id,可以调用多媒体文件下载接口拉取数据。
Format语音格式,如amr,speex等
MsgId消息id,64位整型

视频消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
<MsgId>1234567890123456</MsgId>
</xml>
参数描述
ToUserName开发者微信号
FromUserName发送方帐号(一个OpenID)
CreateTime消息创建时间 (整型)
MsgType视频为video
MediaId视频消息媒体id,可以调用多媒体文件下载接口拉取数据。
ThumbMediaId视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
MsgId消息id,64位整型

小视频消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[shortvideo]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
<MsgId>1234567890123456</MsgId>
</xml>
参数描述
ToUserName开发者微信号
FromUserName发送方帐号(一个OpenID)
CreateTime消息创建时间 (整型)
MsgType小视频为shortvideo
MediaId视频消息媒体id,可以调用多媒体文件下载接口拉取数据。
ThumbMediaId视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
MsgId消息id,64位整型

地理位置消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[location]]></MsgType>
<Location_X>23.134521</Location_X>
<Location_Y>113.358803</Location_Y>
<Scale>20</Scale>
<Label><![CDATA[位置信息]]></Label>
<MsgId>1234567890123456</MsgId>
</xml>
参数描述
ToUserName开发者微信号
FromUserName发送方帐号(一个OpenID)
CreateTime消息创建时间 (整型)
MsgTypelocation
Location_X地理位置维度
Location_Y地理位置经度
Scale地图缩放大小
Label地理位置信息
MsgId消息id,64位整型

链接消息

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[link]]></MsgType>
<Title><![CDATA[公众平台官网链接]]></Title>
<Description><![CDATA[公众平台官网链接]]></Description>
<Url><![CDATA[url]]></Url>
<MsgId>1234567890123456</MsgId>
</xml>
参数描述
ToUserName开发者微信号
FromUserName发送方帐号(一个OpenID)
CreateTime消息创建时间 (整型)
MsgType消息类型,link
Title消息标题
Description消息描述
Url消息链接
MsgId消息id,64位整型

下面需要做的就是将这些消息封装成Java对象

像ToUserName,FromUserName ,CreateTime ,MsgType 所有的消息中都有所以可以将其封装成一个基类,然后分别让具体其他消息类去继承。


package org.sm.message.req;

/**
 * 消息基类(普通用户 -> 公众帐号)
 * 
 * @author sunming
 * @date 2017-08-01
 */
public class BaseMessage {
    // 开发者微信号
    private String ToUserName;
    // 发送方帐号(一个OpenID)
    private String FromUserName;
    // 消息创建时间 (整型)
    private long CreateTime;
    // 消息类型(text/image/location/link)
    private String MsgType;
    // 消息id,64位整型
    private long MsgId;

    public String getToUserName() {
    return ToUserName;
    }

    public void setToUserName(String toUserName) {
    ToUserName = toUserName;
    }

    public String getFromUserName() {
    return FromUserName;
    }

    public void setFromUserName(String fromUserName) {
    FromUserName = fromUserName;
    }

    public long getCreateTime() {
    return CreateTime;
    }

    public void setCreateTime(long createTime) {
    CreateTime = createTime;
    }

    public String getMsgType() {
    return MsgType;
    }

    public void setMsgType(String msgType) {
    MsgType = msgType;
    }

    public long getMsgId() {
    return MsgId;
    }

    public void setMsgId(long msgId) {
    MsgId = msgId;
    }
}

文本消息:

package org.sm.message.req;

/**
 * 文本消息
 * 
 * @author sunming
 * @date 2017-08-01
 */
public class TextMessage extends BaseMessage {
    // 消息内容
    private String Content;

    public String getContent() {
    return Content;
    }

    public void setContent(String content) {
    Content = content;
    }

    @Override
    public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("TextMessage [Content=");
    builder.append(Content);
    builder.append("]");
    return builder.toString();
    }

}

图片消息:


package org.sm.message.req;

/**
 * 图片消息
 * 
 * @author sunming
 * @date 2017-08-01
 */
public class ImageMessage extends BaseMessage {
    // 图片链接
    private String PicUrl;

    public String getPicUrl() {
    return PicUrl;
    }

    public void setPicUrl(String picUrl) {
    PicUrl = picUrl;
    }

    @Override
    public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("ImageMessage [PicUrl=");
    builder.append(PicUrl);
    builder.append("]");
    return builder.toString();
    }

}

链接消息:


package org.sm.message.req;

/**
 * 链接消息
 * 
 * @author sunming
 * @date 2017-08-01
 */
public class LinkMessage extends BaseMessage {
    // 消息标题
    private String Title;
    // 消息描述
    private String Description;
    // 消息链接
    private String Url;

    public String getTitle() {
    return Title;
    }

    public void setTitle(String title) {
    Title = title;
    }

    public String getDescription() {
    return Description;
    }

    public void setDescription(String description) {
    Description = description;
    }

    public String getUrl() {
    return Url;
    }

    public void setUrl(String url) {
    Url = url;
    }

    @Override
    public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("LinkMessage [Title=");
    builder.append(Title);
    builder.append(", Description=");
    builder.append(Description);
    builder.append(", Url=");
    builder.append(Url);
    builder.append("]");
    return builder.toString();
    }

}

位置消息:


package org.sm.message.req;

/**
 * 地理位置消息
 * 
 * @author sunming
 * @date 2017-08-01
 */
public class LocationMessage extends BaseMessage {
    // 地理位置维度
    private String Location_X;
    // 地理位置经度
    private String Location_Y;
    // 地图缩放大小
    private String Scale;
    // 地理位置信息
    private String Label;

    public String getLocation_X() {
    return Location_X;
    }

    public void setLocation_X(String location_X) {
    Location_X = location_X;
    }

    public String getLocation_Y() {
    return Location_Y;
    }

    public void setLocation_Y(String location_Y) {
    Location_Y = location_Y;
    }

    public String getScale() {
    return Scale;
    }

    public void setScale(String scale) {
    Scale = scale;
    }

    public String getLabel() {
    return Label;
    }

    public void setLabel(String label) {
    Label = label;
    }

    @Override
    public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("LocationMessage [Location_X=");
    builder.append(Location_X);
    builder.append(", Location_Y=");
    builder.append(Location_Y);
    builder.append(", Scale=");
    builder.append(Scale);
    builder.append(", Label=");
    builder.append(Label);
    builder.append("]");
    return builder.toString();
    }

}

语言消息


package org.sm.message.req;

/**
 * 语音消息
 * 
 * @author sunming
 * @date 2017-08-01
 */
public class VoiceMessage extends BaseMessage {
    // 媒体ID
    private String MediaId;
    // 语音格式
    private String Format;

    public String getMediaId() {
    return MediaId;
    }

    public void setMediaId(String mediaId) {
    MediaId = mediaId;
    }

    public String getFormat() {
    return Format;
    }

    public void setFormat(String format) {
    Format = format;
    }

    @Override
    public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("VoiceMessage [MediaId=");
    builder.append(MediaId);
    builder.append(", Format=");
    builder.append(Format);
    builder.append("]");
    return builder.toString();
    }

}

视频消息:

package org.sm.message.req;

public class VideoMessage extends BaseMessage {

    private String MediaId;
    private String ThumbMediaId;

    public String getMediaId() {
    return MediaId;
    }

    public void setMediaId(String mediaId) {
    MediaId = mediaId;
    }

    public String getThumbMediaId() {
    return ThumbMediaId;
    }

    public void setThumbMediaId(String thumbMediaId) {
    ThumbMediaId = thumbMediaId;
    }

    @Override
    public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("VideoMessage [MediaId=");
    builder.append(MediaId);
    builder.append(", ThumbMediaId=");
    builder.append(ThumbMediaId);
    builder.append("]");
    return builder.toString();
    }
}

二.请求消息的解析

微信用户向公众账号发消息时发送的是XML消息包,所以我们需要将XML解析成我们需要的东西,解析XML我们使用dom4j,首先引入jar包dom4j-1.6.1.jar
然后写一个解析XML工具类


package org.sm.util;

import java.io.InputStream;
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;


/**
 * 消息工具类
 * 
 * @author sunming
 * @date 2017-08-01
 */
public class MessageUtil {

    /**
     * 解析微信发来的请求(XML)
     * 
     * @param request
     * @return
     * @throws Exception
     */
    @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;
    }

}

我们来看看解析的效果,在ServiceServlet的post方法中加一些东西

 /**
     * 处理微信服务器发来的消息
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");

    Map<String, String> map = null;
    try {
        map = MessageUtil.parseXml(request);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println(map);
    }

用手机向公众发送一句话看看控制台能否打印出map来

{Content=你好, CreateTime=1502288237, ToUserName=gh_5f5e0f3dd11c, FromUserName=oSIie1JNtmbUBG-6F6BTC9tDytO0, MsgType=text, MsgId=6452278847529990076}

说明解析ok了,那公众号该给用户回复点啥呢,下次再说

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值