上一篇讲了通过封装json格式数据测试自定义菜单功能,这篇讲基础消息能力的接收普通消息和被动回复用户消息。
1.引入
开始我们将自己的服务器与微信服务器进行绑定时,将微信的GET请求获取并作了相关的验证,而对于用户在公众号上发消息等操作的时候微信服务器也会通过POST请求发送到我们填写的URL上,我们可以根据收到的信息进行相关的响应回复操作。
2.测试用户发消息操作,本地收到的POST请求 WeCharController
//获取微信返回数据
@PostMapping
public String getWeChar(@RequestBody String message) throws Exception {
System.out.println("接收到微信返回的消息:"+message);
return null;
}
控制台信息,可以看到,当在微信公众号发送文字消息时,本地服务收到如下消息。
ToUserName: gh_1e06f4c4ca61 开发者微信号
FromUserName: oITpR58LM-HJG0Fa4BY6MkOCG5lM 发送方帐号(一个OpenID)
CreateTime:1664693332 消息创建时间 (整型)
MsgType :text 消息类型,文本为text
Content: 文本消息内容
MsgId :消息id,64位整型
接收到微信返回的消息:
1664693332
23832676103729051
图片消息特有的信息:
PicUrl: 图片链接(由系统生成)
MediaId:图片消息媒体id,可以调用获取临时素材接口拉取数据。
MsgId:消息id,64位整型
MsgDataId: 消息的数据ID(消息如果来自文章时才有)
接收到微信返回的消息:
1664693659
23832682835649773
语音消息特有的信息:
Format:语音格式:amr
Recognition: 语音识别结果,UTF8编码
接收到微信返回的消息:
1664693943
23832683876255433
未开启接收语音识别结果权限Recognition是空的,因此开启接收语音识别结果权限
文章图片
接收到微信返回的消息:
1664694297
7149807563452710912
【spring|SpringCloud Alibaba 开发微信公众号 (基础消息能力)】其他消息,就不再介绍了,基本上不同的消息都会有自己特有的属性,其他属性则是各种消息所共有的。
3.被动响应用户的消息
当我们服务器收到用户的一些消息操作时,我们可以通过收到的消息类型、消息内容进行相应的回复操作。从上面的收到的消息信息可以看出,我们收到的消息是XML格式的信息,因此我们需要将其转为MAP格式数据从而方便我们的处理,同时再将要响应的结果转为XML进行返回。
引入相关依赖
org.dom4j
dom4j
2.1.1
com.thoughtworks.xstream
xstream
1.4.10
其中dom4j依赖的DocumentHelper.parseText方法 是将给定文本 XML解析为新创建的 Document。我们通过对Document遍历赋值转为MAP格式数据。
而xstream依赖的toXML方法是将对象转化为XML信息进行返回(其中对象属性上需要增加 @XStreamAlias(“相关字段”)注解)。
创建XmlUtils 转化处理工具类
import com.thoughtworks.xstream.XStream;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* XML对象处理类
*
* @auther: wanghongjie
* @blame: wanghongjie
* @date: 2020-08-30 17:31
* @Description:
*/
public class XmlUtils {/**
* 将xml格式的字符串转换成Map对象
*
* @param xmlStr xml格式的字符串
* @return Map对象
* @throws Exception 异常
*/
public static Map xmlStrToMap(String xmlStr) throws Exception {
if (StringUtils.isEmpty(xmlStr)) {
return null;
}
Map map = new HashMap<>(16);
//将xml格式的字符串转换成Document对象
Document doc = DocumentHelper.parseText(xmlStr);
//获取根节点
Element root = doc.getRootElement();
//获取根节点下的所有元素
List children = root.elements();
//循环所有子元素
if (children != null && children.size() > 0) {
for (Object o : children) {
Element child = (Element) o;
map.put(child.getName(), child.getTextTrim());
}
}
return map;
}public static String beanToXml(Object object, Class cls) {
XStream stream = new XStream();
stream.processAnnotations(cls);
return stream.toXML(object);
}}
创建公共消息参数处理类BaseMessage (任何消息的公共属性类,对应具体消息只需要继承该类即可)
import com.ctsi.sddx.constants.WeCharConstant;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
/**
* 公共消息参数处理类
* Created with IntelliJ IDEA.
* User:wanghongjie
* Date:2020/10/17 - 09:56
* * Description:
*/
@Data
public class BaseMessage implements Serializable {
/**
* 消息ID 64位整型
*/
@XStreamAlias("MsgId")
private String msgId;
/**
* 开发者微信号
*/
@XStreamAlias("ToUserName")
private String toUserName;
/**
* 发送方帐号(一个OpenID)
*/
@XStreamAlias("FromUserName")
private String fromUserName;
/**
* 消息创建时间 (整型)
*/
@XStreamAlias("CreateTime")
private String createTime;
/**
* 消息类型,文本为text
*/
@XStreamAlias("MsgType")
private String msgType;
void init(Map map) {
this.createTime = String.valueOf(map.get(WeCharConstant.CREATE_TIME));
this.fromUserName = String.valueOf(map.get(WeCharConstant.FROM_USER_NAME));
this.toUserName = String.valueOf(map.get(WeCharConstant.TO_USER_NAME));
this.msgType = String.valueOf(map.get(WeCharConstant.MSG_TYPE));
this.msgId = String.valueOf(map.get(WeCharConstant.MSG_ID));
}
}
文本消息实体类TextMessage
import cn.org.spring.common.util.XmlUtils;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
import java.util.Map;
/**
* Created with IntelliJ IDEA.
* User:wanghongjie
* Date:2020/10/17 - 10:01
* * Description:
*/
@Data
@XStreamAlias("xml")
public class TextMessage extends BaseMessage {@XStreamAlias("Content")
private String content;
public static TextMessage of(Map objectMap, String content) {
TextMessage textMessage = new TextMessage();
textMessage.init(objectMap);
textMessage.setContent(content);
return textMessage;
}public static TextMessage ofSendMsg(Map objectMap, String content) {
TextMessage textMessage = new TextMessage();
textMessage.init(objectMap);
textMessage.setContent(content);
textMessage.setMsgType("text");
String from = textMessage.getFromUserName();
textMessage.setFromUserName(textMessage.getToUserName());
textMessage.setToUserName(from);
return textMessage;
}public String toXml() {
return XmlUtils.beanToXml(this, TextMessage.class);
}
}
测试 WeCharController
// 获取微信返回数据
@PostMapping
public String getWeChar(@RequestBody String message) throws Exception {
System.out.println(“接收到微信返回的消息:”+message);
Map stringObjectMap = XmlUtils.xmlStrToMap(message);
TextMessage textMessage = TextMessage.ofSendMsg(stringObjectMap, "你好呀,欢迎关注我的测试公众号!");
String responseMessage = textMessage.toXml();
System.out.println("响应微信平台的消息:"+responseMessage);
return responseMessage;
}
控制台输出:
接收到微信返回的消息:
1664696395
23832721292703678
响应微信平台的消息:
23832721292703678
oITpR5-x01JQu8doRMMgaFDYU3eM
gh_1e06f4c4ca61
1664696395
text
你好呀,欢迎关注我的测试公众号!
测试号响应效果:
文章图片
思考
当你这么写的话貌似把响应信息的处理写死了,无论你发送的是文本信息,还是图片信息、语音信息他都会只回复这个信息。
文章图片
首先想到的就是通过微信发来的POST请求进行类型判断,如果是文本信息怎么怎么回复,如果是图片信息我怎么怎么回复,如果是语音信息怎么怎么回复。。。。
下篇文章:
使用策略模式处理复杂消息
推荐阅读
- springboot|基于SpringBoot的汽车租赁管理系统
- Maven入门实战|maven的生命周期和单元测试junit-打包-安装
- hashmap|JDK 经典操作 之 HashMap 7、8 之间的差别
- java|掘金社区自动签到+免费抽奖
- Linux服务器|SpringCloud实用篇02
- 框架|IV XXSC-10
- web|Web全栈~32.深入理解synchronized
- Java从入门到精通(二)|Java中的循环语句
- java|计算平均成绩【JAVA】