微信测试号开发之三 接收处理消息并响应
原文:https://blog.csdn.net/qq_37936542/article/details/78340462
根据配置的URL,微信第一次验证请求发送GET请求,之后发送的消息都是发送POST请求到该URL上,我们看看之前写的post方法
- /**
- * 消息的处理和响应
- * @param request
- * @param response
- * @throws Exception
- */
- @RequestMapping(value="handle",method=RequestMethod.POST)
- public void messageHandle(HttpServletRequest request,HttpServletResponse response) throws Exception{
- }
request中封装了微信发送过来的所有信息,
response用来对微信服务器进行响应。
一:准备需要的jar包或依赖
服务器解析微信发过来的xml数据需要用到 -- 开源框架dom4j
jar包下载地址:http://www.dom4j.org/dom4j-1.6.1/
maven依赖:
- <dependency>
- <groupId>dom4j</groupId>
- <artifactId>dom4j</artifactId>
- <version>1.6</version>
- </dependency>
服务器响应微信时将内容转为xml格式数据需要使用到 -- 开源框架xstream
maven依赖:
- <dependency>
- <groupId>com.thoughtworks.xstream</groupId>
- <artifactId>xstream</artifactId>
- <version>1.4.7</version>
- </dependency>
二:封装一个消息处理类,提供方法用来获取requst中内容,装入map,将回复的内容转为xml格式的数据
- import java.io.InputStream;
- import java.io.Writer;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import javax.servlet.http.HttpServletRequest;
- import org.dom4j.Document;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- import com.mote.weixin.entry.Response_Text;
- import com.thoughtworks.xstream.XStream;
- import com.thoughtworks.xstream.core.util.QuickWriter;
- import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
- import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
- import com.thoughtworks.xstream.io.xml.XppDriver;
- public class MessageUtils {
- // 请求消息类型:文本
- public static final String REQ_MESSAGE_TYPE_TEXT = "text";
- // 请求消息类型:图片
- public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
- // 请求消息类型:语音
- public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
- // 请求消息类型:视频
- public static final String REQ_MESSAGE_TYPE_VIDEO = "video";
- // 请求消息类型:小视频
- public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo";
- // 请求消息类型:地理位置
- public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
- // 请求消息类型:链接
- public static final String REQ_MESSAGE_TYPE_LINK = "link";
- // 请求消息类型:事件推送
- public static final String REQ_MESSAGE_TYPE_EVENT = "event";
- // 事件类型:subscribe(订阅)
- public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
- // 事件类型:unsubscribe(取消订阅)
- public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
- // 事件类型:scan(用户已关注时的扫描带参数二维码)
- public static final String EVENT_TYPE_SCAN = "scan";
- // 事件类型:LOCATION(上报地理位置)
- public static final String EVENT_TYPE_LOCATION = "LOCATION";
- // 事件类型:CLICK(自定义菜单)
- public static final String EVENT_TYPE_CLICK = "CLICK";
- // 响应消息类型:文本
- public static final String RESP_MESSAGE_TYPE_TEXT = "text";
- // 响应消息类型:图片
- public static final String RESP_MESSAGE_TYPE_IMAGE = "image";
- // 响应消息类型:语音
- public static final String RESP_MESSAGE_TYPE_VOICE = "voice";
- // 响应消息类型:视频
- public static final String RESP_MESSAGE_TYPE_VIDEO = "video";
- // 响应消息类型:音乐
- public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
- // 响应消息类型:图文
- public static final String RESP_MESSAGE_TYPE_NEWS = "news";
- /**
- * 解析微信发来的请求(XML)封装成map
- *
- * @param request
- * @return Map<String, String>
- * @throws Exception
- */
- @SuppressWarnings("unchecked")
- public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
- // 将解析结果存储在HashMap中
- Map<String, String> map = new HashMap<String, String>();
- // 从request中取得输入流
- InputStream inputStream = request.getInputStream();
- // 读取输入流
- SAXReader reader = new SAXReader();
- Document document = reader.read(inputStream);
- // 得到xml根元素
- Element root = document.getRootElement();
- // 得到根元素的所有子节点
- List<Element> elementList = root.elements();
- // 遍历所有子节点
- for (Element e : elementList)
- map.put(e.getName(), e.getText());
- // 释放资源
- inputStream.close();
- inputStream = null;
- return map;
- }
- /**
- * 扩展xstream使其支持CDATA
- */
- 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);
- }
- }
- };
- }
- });
- /**
- * 文本响应消息对象转换成xml
- *
- * @param textMessage 文本消息对象
- * @return xml
- */
- public static String messageToXml(RespMessage_Text responseText) {
- xstream.alias("xml", responseText.getClass());
- return xstream.toXML(responseText);
- }
- }
三:写一个CoreService来完成主要业务
- import java.util.Date;
- import java.util.Map;
- import javax.servlet.http.HttpServletRequest;
- import com.mote.weixin.entry.Response_Text;
- import com.mote.weixin.utils.MessageUtils;
- public class CoreService {
- public static String processRequest(HttpServletRequest request)
- throws Exception {
- // 返回的xml数据
- String resqXml = null;
- // 返回的文本内容
- String resqContext = null;
- // 将request交给消息处理类
- Map<String, String> map = MessageUtils.parseXml(request);
- // 获取消息类型
- String msgType = map.get("MsgType");
- // 封装返回消息
- RespMessage_Text responseText = new RespMessage_Text();
- responseText.setFromUserName(map.get("ToUserName"));
- responseText.setToUserName(map.get("FromUserName"));
- responseText.setCreateTime(new Date().getTime());
- // 根据不同消息类型做出相应的处理
- // 文本消息
- if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_TEXT)) {
- resqContext = "您发送了文本消息";
- }
- // 图片消息
- if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_IMAGE)) {
- resqContext = "您发送了图片消息";
- }
- //事件消息
- if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_EVENT)) {
- //获取事件类型
- String eventType = map.get("EVENT");
- if(eventType.equals(MessageUtils.EVENT_TYPE_SUBSCRIBE)){
- //关注
- resqContext = "谢谢你的关注";
- }
- if(eventType.equals(MessageUtils.EVENT_TYPE_UNSUBSCRIBE)){
- //TODO取消关注
- }
- if(eventType.equals(MessageUtils.EVENT_TYPE_CLICK)){
- //TODO自定义菜单
- }
- if(eventType.equals(MessageUtils.EVENT_TYPE_SCAN)){
- //TODO扫描二维码
- }
- }
- //设置返回内容
- responseText.setContent(resqContext);
- //将对象转为xml数据
- resqXml = MessageUtils.messageToXml(responseText);
- return resqXml;
- }
- }
四:在post方法中调用CoreService处理业务
- /**
- * 消息的处理和响应
- * @param request
- * @param response
- * @throws Exception
- */
- @RequestMapping(value="handle",method=RequestMethod.POST)
- public void messageHandle(HttpServletRequest request,HttpServletResponse response) throws Exception{
- //将请求、响应的编码设置为utf-8
- request.setCharacterEncoding("UTF-8");
- response.setCharacterEncoding("UTF-8");
- //调用核心业务逻辑
- String respXml = CoreService.processRequest(request);
- //响应消息
- PrintWriter out = response.getWriter();
- out.print(respXml);
- out.close();
- }
文末福利:
福利一:前端,Java,产品经理,微信小程序,Python等10G资源合集大放送:https://www.jianshu.com/p/e8197d4d9880
福利二:微信小程序入门与实战全套详细视频教程。
【领取方法】
关注 【编程微刊】微信公众号:
回复【小程序demo】一键领取130个微信小程序源码demo资源。
回复【领取资源】一键领取前端,Java,产品经理,微信小程序,Python等资源合集10G资源大放送。
原文作者:祈澈姑娘
原文链接:https://www.jianshu.com/u/05f416aefbe1
创作不易,转载请告知
90后前端妹子,爱编程,爱运营,爱折腾。
坚持总结工作中遇到的技术问题,坚持记录工作中所所思所见,欢迎大家一起探讨交流。