前提:服務端程序和微信測試平臺已經打通。
沒打通的可以參考我前面的文章。
公衆號開發文檔:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html
今天的主題是消息,我們主要完成兩個功能。
1、用戶通過關注測試公衆號平臺給服務端傳遞數據。
2、服務端對數據作出及時反饋。
1、用戶通過關注測試公衆號平臺給服務端傳遞數據。
申請到測試公衆號平臺的朋友,打開後臺,有個測試二維碼,關注一下就能給後臺發消息了。
關注公衆號以後,隨便在公衆號發幾條消息,他會給你提供的url地址發送一個post請求。我們可以把消息打印出來瞅瞅。
post請求發來的數據是一段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>
用戶發送的類型分爲好多種,包括文本(表情也是文本),視頻,語音,位置等等。基本數據包長的都差不多,可以多發幾種打印出來看看。也可以參考官方文檔。
這麼一串xml我們通過程序將其轉換爲map,用的dom4j。這樣我們就能很好的對用戶發來的數據包物盡其用了。
@PostMapping("/get")
private String get(HttpServletRequest request) {
Map<String, String> requestMap = weChatService.parse(request);
System.out.println("requestMap="+requestMap);
return "";
}
//解析XML =》 Map
@Override
public Map<String, String> parse(HttpServletRequest request) {
Map<String, String> map = new HashMap<>();
try {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(request.getInputStream());
Element root = document.getRootElement();
List<Element> elements = root.elements();
for (Element element : elements) {
map.put(element.getName(), element.getStringValue());
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
2、服務端對數據作出及時反饋。
接下來要對用戶發來的消息作出一個反饋,很簡單,只要在response一段xml數據就好了。
這個xml格式是有要求的,大概是這個樣子。
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
toUserName是接收map裏的fromUserName,fromUserName同理反一下。
CreateTime就是當前時間,System.currentTimeMillis() / 1000
MsgType和上面一樣,分爲文本,圖片,視頻等等。
想要簡單粗暴的方法直接在controller裏直接return上面一段數據就行了(注意不要出現空格)
我這邊封裝了一個對象,用工具類(XStream)將對象轉爲xml返回。
封裝的時候發現ToUserName,FromUserName,CreateTime一定有,就抽取成一個base類了。
/**
* 公衆號開發自動回覆的基礎類
*/
public class BaseMessage {
@XStreamAlias("ToUserName")
private String toUserName;
@XStreamAlias("FromUserName")
private String fromUserName;
@XStreamAlias("CreateTime")
private String createTime;
@XStreamAlias("MsgType")
private String msgType;
public BaseMessage(Map<String,String> requestMap, String msgType) {
this.toUserName = requestMap.get("FromUserName");
this.fromUserName = requestMap.get("ToUserName");
this.createTime = System.currentTimeMillis() / 1000 + "";
this.msgType = msgType;
}
public String getToUserName() {
return toUserName;
}
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public String getFromUserName() {
return fromUserName;
}
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
}
然後文本消息或者其他視頻消息,圖文消息在繼承這個Base類。
/**
* 公衆號開發自動回覆文本消息類
*/
@XStreamAlias("xml")
public class TextMessage extends BaseMessage {
@XStreamAlias("Content")
private String content;
public TextMessage(Map<String, String> requestMap, String content) {
super(requestMap, "text");
this.content = content;
}
}
Controller就只要將對象轉爲數據返回就行
@PostMapping("/get")
private String get(HttpServletRequest request) {
Map<String, String> requestMap = weChatService.parse(request);
System.out.println("requestMap="+requestMap);
String response = weChatService.getResponse(requestMap);
System.out.println(response);
return response;
}
service
//回覆消息模板
// <xml>
// <ToUserName><![CDATA[toUser]]></ToUserName>
// <FromUserName><![CDATA[fromUser]]></FromUserName>
// <CreateTime>12345678</CreateTime>
// <MsgType><![CDATA[text]]></MsgType>
// <Content><![CDATA[你好]]></Content>
//</xml>
@Override
public String getResponse(Map<String, String> requestMap) {
String type = requestMap.get("MsgType");
String responseXml = "";
switch (type) {
case "text":
responseXml = dealTextMessage(requestMap);
break;
case "image":
break;
case "voice":
break;
case "video":
break;
case "music":
break;
case "news":
break;
}
return responseXml;
}
//處理文本信息回覆
private String dealTextMessage(Map<String, String> requestMap) {
TextMessage textMessage = new TextMessage(requestMap, "hello ~~");
XStream xStream = new XStream();
xStream.processAnnotations(TextMessage.class);//激活註解
xStream.alias("xml", TextMessage.class);
return xStream.toXML(textMessage);
}
大致過程就是這樣,以上我只是舉text爲例子,其他類型可能也有些許不同,換湯不換藥~ 大家可以試試。