响应消息的封装与转换

来源:互联网 发布:5g网络是什么的基础 编辑:程序博客网 时间:2024/05/20 20:17

一.响应消息的封装

到目前为止我们的公众号已经可以收到用户发过来的消息,那我们该怎样给用户响应呢,继续往下看。目前微信支持响应的消息有文本、图片、图文、语音、视频、音乐。下面看下各种回复消息的样式。

回复文本消息

<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[你好]]></Content></xml>
参数 是否必须 描述 ToUserName 是 接收方帐号(收到的OpenID) FromUserName 是 开发者微信号 CreateTime 是 消息创建时间 (整型) MsgType 是 text Content 是 回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)

回复图片消息

<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[media_id]]></MediaId></Image></xml>
参数 是否必须 描述 ToUserName 是 接收方帐号(收到的OpenID) FromUserName 是 开发者微信号 CreateTime 是 消息创建时间 (整型) MsgType 是 image MediaId 是 通过素材管理中的接口上传多媒体文件,得到的id。

回复语音消息

<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[voice]]></MsgType><Voice><MediaId><![CDATA[media_id]]></MediaId></Voice></xml>
参数 是否必须 描述 ToUserName 是 接收方帐号(收到的OpenID) FromUserName 是 开发者微信号 CreateTime 是 消息创建时间 (整型) MsgType 是 语音,voice MediaId 是 通过素材管理中的接口上传多媒体文件,得到的id

回复视频消息

<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[media_id]]></MediaId><Title><![CDATA[title]]></Title><Description><![CDATA[description]]></Description></Video> </xml>
参数 是否必须 描述 ToUserName 是 接收方帐号(收到的OpenID) FromUserName 是 开发者微信号 CreateTime 是 消息创建时间 (整型) MsgType 是 video MediaId 是 通过素材管理中的接口上传多媒体文件,得到的id Title 否 视频消息的标题 Description 否 视频消息的描述

回复音乐消息

<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[TITLE]]></Title><Description><![CDATA[DESCRIPTION]]></Description><MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl><HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl><ThumbMediaId><![CDATA[media_id]]></ThumbMediaId></Music></xml>
参数 是否必须 描述 ToUserName 是 接收方帐号(收到的OpenID) FromUserName 是 开发者微信号 CreateTime 是 消息创建时间 (整型) MsgType 是 music Title 否 音乐标题 Description 否 音乐描述 MusicURL 否 音乐链接 HQMusicUrl 否 高质量音乐链接,WIFI环境优先使用该链接播放音乐 ThumbMediaId 是 缩略图的媒体id,通过素材管理中的接口上传多媒体文件,得到的id

回复图文消息

<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[news]]></MsgType><ArticleCount>2</ArticleCount><Articles><item><Title><![CDATA[title1]]></Title> <Description><![CDATA[description1]]></Description><PicUrl><![CDATA[picurl]]></PicUrl><Url><![CDATA[url]]></Url></item><item><Title><![CDATA[title]]></Title><Description><![CDATA[description]]></Description><PicUrl><![CDATA[picurl]]></PicUrl><Url><![CDATA[url]]></Url></item></Articles></xml>
参数 是否必须 描述 ToUserName 是 接收方帐号(收到的OpenID) FromUserName 是 开发者微信号 CreateTime 是 消息创建时间 (整型) MsgType 是 news ArticleCount 是 图文消息个数,限制为8条以内 Articles 是 多条图文消息信息,默认第一个item为大图,注意,如果图文数超过8,则将会无响应 Title 是 图文消息标题 Description 是 图文消息描述 PicUrl 是 图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200 Url 是 点击图文消息跳转链接

和请求消息一样,下面做的就是对这些消息进行封装。

消息基类:

package org.sm.message.rsp;/** * 消息基类 *  * @author sunming * @date 2017-08-10 */public class BaseMessage {    // 接收方帐号(收到的OpenID)    private String ToUserName;    // 开发者微信号    private String FromUserName;    // 消息创建时间 (整型)    private long CreateTime;    // 消息类型(text/music/news)    private String MsgType;    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;    }    @Override    public String toString() {    StringBuilder builder = new StringBuilder();    builder.append("BaseMessage [ToUserName=");    builder.append(ToUserName);    builder.append(", FromUserName=");    builder.append(FromUserName);    builder.append(", CreateTime=");    builder.append(CreateTime);    builder.append(", MsgType=");    builder.append(MsgType);    builder.append("]");    return builder.toString();    }}

文本消息:

package org.sm.message.rsp;/** * 文本消息 *  * @author sunming * @date 2017-08-10 */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();    }}

下面的封装我就不再贴代码了,套路都是一样的。

二.消息的转换

我们对微信平台传过来的消息进行业务逻辑处理然后返回合适的消息类型,逻辑处理的时候操作的对象都是我们封装的POJO,需要返回给微信服务器的是XML数据包,那怎样将POJO转换成XML呢?我们需要使用Xstream 框架,下载xstream-1.3.1.jar.在我们的MessageUtil工具类中添加将封装的Java对象装换成XML方法。

 /**     * 文本消息对象转换成xml     *      * @param textMessage     *            文本消息对象     * @return xml     */    public static String textMessageToXml(TextMessage textMessage) {    xstream.alias("xml", textMessage.getClass());    return xstream.toXML(textMessage);    }    /**     * 扩展xstream,使其支持CDATA块     *      * @date 2017-08-10     */    private static XStream xstream = new XStream(new XppDriver() {    public HierarchicalStreamWriter createWriter(Writer out) {        return new PrettyPrintWriter(out) {        // 对所有xml节点的转换都增加CDATA标记        boolean cdata = true;        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);            }        }        };    }    });

下面我们来试试效果
ServiceServlet类的doPost方法如下:

 /**     * 处理微信服务器发来的消息     */    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();    }    // 发送方帐号(open_id)    String fromUserName = map.get("FromUserName");    // 公众帐号    String toUserName = map.get("ToUserName");    // 消息类型    String msgType = map.get("MsgType");    if ("text".equals(msgType)) {        // 默认回复此文本消息        TextMessage textMessage = new TextMessage();        textMessage.setToUserName(fromUserName);        textMessage.setFromUserName(toUserName);        textMessage.setCreateTime(new Date().getTime());        textMessage.setMsgType("text");        textMessage.setContent("你好,欢迎关注我的公众号");        String respMessage = MessageUtil.textMessageToXml(textMessage);        System.out.println(respMessage);        // 响应消息        PrintWriter out = response.getWriter();        out.print(respMessage);        out.close();    }    }

向公众号发条信息看看

这里写图片描述

控制台打印的响应消息:

<xml>  <ToUserName><![CDATA[oSIie1JNtmbUBG-6F6BTC9tDytO0]]></ToUserName>  <FromUserName><![CDATA[gh_5f5e0f3dd11c]]></FromUserName>  <CreateTime><![CDATA[1502718791724]]></CreateTime>  <MsgType><![CDATA[text]]></MsgType>  <Content><![CDATA[你好,欢迎关注我的公众号]]></Content></xml>

目前为止工程结构:

这里写图片描述