一、接收用户消息
阅读微信开发文档,可以发现,微信当用户给公众号发送消息后,微信服务器将POST消息的XML数据包到开发者填写的URL上。
1、查看接收到的xml数据包
/**
* 接收微信服务器发送过来的消息
* @param request
* @param response
* @return
* @throws IOException
*/
@PostMapping("/check")
public String responseMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletInputStream is = request.getInputStream();
byte[] b = new byte[1024];
int len;
StringBuffer sb = new StringBuffer();
while ((len=is.read(b))!=-1){
sb.append(new String(b,0,len));
}
System.out.println(sb.toString());
return null;
}
可以看到接收到的xml数据包内容,以及用户发送过来的消息。每个节点信息的意义请查看文档,这里不做过多解释。
2、解析xml数据包
解析部分关键代码如下:
/**
* 解析用户发送过来的xml,返回map键值对
* @param is
* @return
*/
public static Map<String, String> parseRquest(ServletInputStream is) {
Map<String,String> map = new HashMap<>();
SAXReader reader = new SAXReader();
try {
//读取输入流,获取文档对象
Document document = reader.read(is);
//根据文档对象获取节点
Element root = document.getRootElement();
//根据根节点获取所有子节点
List<Element> elements = root.elements();
for (Element e:elements) {
map.put(e.getName(),e.getStringValue());
}
} catch (DocumentException e) {
e.printStackTrace();
}
return map;
}
二、回复用户消息
查看微信开发文档,回复用户消息可以看出,回复消息也需要回复xml内容。
1、测试返回数据
首先使用最基础的xml对消息进行回复。
/**
* 接收微信服务器发送过来的消息,推送事件
* @param request
* @param response
* @return
* @throws IOException
*/
@PostMapping("/check")
public String responseMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
Map<String,String> requestMap = CheckUtil.parseRquest(request.getInputStream());
System.out.println(requestMap);
//测试使用,准备回复的数据包,直接去文档复制粘贴过来.然后根据map替换自己的ToUserName和FromUserName
String resxml = "<xml><ToUserName><![CDATA["+requestMap.get("FromUserName")+"]]></ToUserName><FromUserName><![CDATA["+requestMap.get("ToUserName")+"]]></FromUserName><CreateTime>"+System.currentTimeMillis()/1000+"</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[你好啦啦啦]]>/Content></xml>";
return resxml;
}
测试可行。
2、封装回复用户消息的类
演示只封装文本回复,进行测试
逻辑处理的方法
/**
* 用户处理所有的事件和消息回复
* @param requestMap
* @return xml数据包
*/
public static String getResponseXml(Map<String, String> requestMap) {
BaseMessage msg =null;
String msgType = requestMap.get("MsgType");
switch (msgType){
case "text":
msg = DealMessageUtil.dealTextMessage(requestMap);
break;
case "image":
break;
case "voice":
break;
...
}
}
消息处理工具类中的文本处理:
/**
* 处理各种类型消息的工具类
*/
public class DealMessageUtil {
public static BaseMessage dealTextMessage(Map<String, String> requestMap) {
TextMessage textMessage = new TextMessage(requestMap,"这就是文本回复");
return textMessage;
}
}
文本实体类:
public class TextMessage extends BaseMessage{
//消息内容
private String content;
public TextMessage(Map<String,String> requestMap,String content){
super(requestMap);
//设置文本消息类型为text
this.setMsgType("text");
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
消息类父类:(删除了get()、set()方法)
public class BaseMessage {
//开发者微信号
private String toUserName;
//发送方帐号(一个OpenID)
private String fromUserName;
//消息创建时间 (整型)
private String createTime;
//消息类型
private String msgType;
public BaseMessage(Map<String,String> requestMap){
this.setToUserName(requestMap.get("FromUserName"));
this.setFromUserName(requestMap.get("ToUserName"));
this.createTime = System.currentTimeMillis()/1000+"";
}
...
}
编写测试类:
public class TestWX {
@Test
public void testMsg(){
Map<String,String> map = new HashMap<>();
map.put("ToUserName","to");
map.put("FromUserName","from");
map.put("MsgType","type");
TextMessage tm = new TextMessage(map,"嘿嘿");
System.out.println(tm);
}
}
返回结果:
3、回复消息处理成xml
实现依靠工具类
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.7</version>
</dependency>
在测试类中进行测试:
发现节点名字存在问题,使用注解处理节点名字
在对应根节点添加注解
修改测试代码:
这句代码作用是使程序查看注解
接下来修改子节点,同理处理,在字段上加注解:
其余处理同理
可以关注我的微信公众号,包含丰富的Java学习资料以及日常的Java开发中遇到的有趣事儿。
期待你的关注,让我们共同进步!
第一部分:环境搭建