前提:服务端程序和微信测试平台已经打通。
没打通的可以参考我前面的文章。
公众号开发新手快速上路(Java版本)
公众号开发文档:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html
今天的主题是消息,我们主要完成两个功能。
1、用户通过关注测试公众号平台给服务端传递数据。
2、服务端对数据作出及时反馈。
申请到测试公众号平台的朋友,打开后台,有个测试二维码,关注一下就能给后台发消息了。
关注公众号以后,随便在公众号发几条消息,他会给你提供的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;
}
接下来要对用户发来的消息作出一个反馈,很简单,只要在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
//回复消息模板
//
//
//
// 12345678
//
//
//
@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为例子,其他类型可能也有些许不同,换汤不换药~ 大家可以试试。