一.響應消息的封裝
到目前爲止我們的公衆號已經可以收到用戶發過來的消息,那我們該怎樣給用戶響應呢,繼續往下看。目前微信支持響應的消息有文本、圖片、圖文、語音、視頻、音樂。下面看下各種回覆消息的樣式。
回覆文本消息
<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>
目前爲止工程結構: