響應消息的封裝與轉換

一.響應消息的封裝

到目前爲止我們的公衆號已經可以收到用戶發過來的消息,那我們該怎樣給用戶響應呢,繼續往下看。目前微信支持響應的消息有文本、圖片、圖文、語音、視頻、音樂。下面看下各種回覆消息的樣式。

回覆文本消息

<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>

目前爲止工程結構:

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章