微信测试号开发之三 接收处理消息并响应

原文:https://blog.csdn.net/qq_37936542/article/details/78340462

根据配置的URL,微信第一次验证请求发送GET请求,之后发送的消息都是发送POST请求到该URL上,我们看看之前写的post方法

       

  1.   /** 
  2. * 消息的处理和响应 
  3. * @param request 
  4. * @param response 
  5. * @throws Exception  
  6. */  
  7. @RequestMapping(value="handle",method=RequestMethod.POST)  
  8. public void messageHandle(HttpServletRequest request,HttpServletResponse response) throws Exception{  
  9.      
  10.   
  11. }  

request中封装了微信发送过来的所有信息,

response用来对微信服务器进行响应。



一:准备需要的jar包或依赖


服务器解析微信发过来的xml数据需要用到 -- 开源框架dom4j  

jar包下载地址:http://www.dom4j.org/dom4j-1.6.1/

maven依赖:

 

  1.    <dependency>  
  2. <groupId>dom4j</groupId>  
  3. <artifactId>dom4j</artifactId>  
  4. <version>1.6</version>  
  5. </dependency>  

服务器响应微信时将内容转为xml格式数据需要使用到 -- 开源框架xstream

maven依赖:

            

  1.   <dependency>  
  2. <groupId>com.thoughtworks.xstream</groupId>  
  3. <artifactId>xstream</artifactId>  
  4. <version>1.4.7</version>  
  5. </dependency>  


二:封装一个消息处理类,提供方法用来获取requst中内容,装入map,将回复的内容转为xml格式的数据


  1. import java.io.InputStream;  
  2. import java.io.Writer;  
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6.   
  7.   
  8. import javax.servlet.http.HttpServletRequest;  
  9.   
  10.   
  11. import org.dom4j.Document;  
  12. import org.dom4j.Element;  
  13. import org.dom4j.io.SAXReader;  
  14.   
  15.   
  16. import com.mote.weixin.entry.Response_Text;  
  17. import com.thoughtworks.xstream.XStream;  
  18. import com.thoughtworks.xstream.core.util.QuickWriter;  
  19. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;  
  20. import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;  
  21. import com.thoughtworks.xstream.io.xml.XppDriver;  
  22.   
  23.   
  24. public class MessageUtils {  
  25. // 请求消息类型:文本  
  26.     public static final String REQ_MESSAGE_TYPE_TEXT = "text";  
  27.     // 请求消息类型:图片  
  28.     public static final String REQ_MESSAGE_TYPE_IMAGE = "image";  
  29.     // 请求消息类型:语音  
  30.     public static final String REQ_MESSAGE_TYPE_VOICE = "voice";  
  31.     // 请求消息类型:视频  
  32.     public static final String REQ_MESSAGE_TYPE_VIDEO = "video";  
  33.     // 请求消息类型:小视频  
  34.     public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo";  
  35.     // 请求消息类型:地理位置  
  36.     public static final String REQ_MESSAGE_TYPE_LOCATION = "location";  
  37.     // 请求消息类型:链接  
  38.     public static final String REQ_MESSAGE_TYPE_LINK = "link";  
  39.   
  40.   
  41.     // 请求消息类型:事件推送  
  42.     public static final String REQ_MESSAGE_TYPE_EVENT = "event";  
  43.   
  44.   
  45.     // 事件类型:subscribe(订阅)  
  46.     public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";  
  47.     // 事件类型:unsubscribe(取消订阅)  
  48.     public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";  
  49.     // 事件类型:scan(用户已关注时的扫描带参数二维码)  
  50.     public static final String EVENT_TYPE_SCAN = "scan";  
  51.     // 事件类型:LOCATION(上报地理位置)  
  52.     public static final String EVENT_TYPE_LOCATION = "LOCATION";  
  53.     // 事件类型:CLICK(自定义菜单)  
  54.     public static final String EVENT_TYPE_CLICK = "CLICK";  
  55.   
  56.   
  57.     // 响应消息类型:文本  
  58.     public static final String RESP_MESSAGE_TYPE_TEXT = "text";  
  59.     // 响应消息类型:图片  
  60.     public static final String RESP_MESSAGE_TYPE_IMAGE = "image";  
  61.     // 响应消息类型:语音  
  62.     public static final String RESP_MESSAGE_TYPE_VOICE = "voice";  
  63.     // 响应消息类型:视频  
  64.     public static final String RESP_MESSAGE_TYPE_VIDEO = "video";  
  65.     // 响应消息类型:音乐  
  66.     public static final String RESP_MESSAGE_TYPE_MUSIC = "music";  
  67.     // 响应消息类型:图文  
  68.     public static final String RESP_MESSAGE_TYPE_NEWS = "news";  
  69.   
  70.   
  71.     /** 
  72.      * 解析微信发来的请求(XML)封装成map 
  73.      *  
  74.      * @param request 
  75.      * @return Map<String, String> 
  76.      * @throws Exception 
  77.      */  
  78.     @SuppressWarnings("unchecked")  
  79.     public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {  
  80.         // 将解析结果存储在HashMap中  
  81.         Map<String, String> map = new HashMap<String, String>();  
  82.   
  83.   
  84.         // 从request中取得输入流  
  85.         InputStream inputStream = request.getInputStream();  
  86.         // 读取输入流  
  87.         SAXReader reader = new SAXReader();  
  88.         Document document = reader.read(inputStream);  
  89.         // 得到xml根元素  
  90.         Element root = document.getRootElement();  
  91.         // 得到根元素的所有子节点  
  92.         List<Element> elementList = root.elements();  
  93.   
  94.   
  95.         // 遍历所有子节点  
  96.         for (Element e : elementList)  
  97.             map.put(e.getName(), e.getText());  
  98.   
  99.   
  100.         // 释放资源  
  101.         inputStream.close();  
  102.         inputStream = null;  
  103.   
  104.   
  105.         return map;  
  106.     }  
  107.   
  108.   
  109.     /** 
  110.      * 扩展xstream使其支持CDATA 
  111.      */  
  112. private static XStream xstream = new XStream(new XppDriver() {  
  113.         public HierarchicalStreamWriter createWriter(Writer out) {  
  114.             return new PrettyPrintWriter(out) {  
  115.                 // 对所有xml节点的转换都增加CDATA标记  
  116.                 boolean cdata = true;  
  117.   
  118.   
  119.                 public void startNode(String name, Class clazz) {  
  120.                     super.startNode(name, clazz);  
  121.                 }  
  122.   
  123.   
  124.                 protected void writeText(QuickWriter writer, String text) {  
  125.                     if (cdata) {  
  126.                         writer.write("<![CDATA[");  
  127.                         writer.write(text);  
  128.                         writer.write("]]>");  
  129.                     } else {  
  130.                         writer.write(text);  
  131.                     }  
  132.                 }  
  133.             };  
  134.         }  
  135.     });  
  136.   
  137.   
  138.     /** 
  139.      * 文本响应消息对象转换成xml 
  140.      *  
  141.      * @param textMessage 文本消息对象 
  142.      * @return xml 
  143.      */  
  144.     public static String messageToXml(RespMessage_Text responseText) {  
  145.         xstream.alias("xml", responseText.getClass());  
  146.         return xstream.toXML(responseText);  
  147.     }  
  148.   
  149.   
  150. }  


三:写一个CoreService来完成主要业务


  1. import java.util.Date;  
  2. import java.util.Map;  
  3. import javax.servlet.http.HttpServletRequest;  
  4. import com.mote.weixin.entry.Response_Text;  
  5. import com.mote.weixin.utils.MessageUtils;  
  6.   
  7.   
  8. public class CoreService {  
  9.   
  10.   
  11. public static String processRequest(HttpServletRequest request)  
  12. throws Exception {  
  13. // 返回的xml数据  
  14. String resqXml = null;  
  15. // 返回的文本内容  
  16. String resqContext = null;  
  17.   
  18.   
  19. // 将request交给消息处理类  
  20. Map<String, String> map = MessageUtils.parseXml(request);  
  21.   
  22.   
  23. // 获取消息类型  
  24. String msgType = map.get("MsgType");  
  25.   
  26.   
  27. // 封装返回消息  
  28. RespMessage_Text responseText = new RespMessage_Text();  
  29. responseText.setFromUserName(map.get("ToUserName"));  
  30. responseText.setToUserName(map.get("FromUserName"));  
  31. responseText.setCreateTime(new Date().getTime());  
  32.   
  33.   
  34. // 根据不同消息类型做出相应的处理  
  35. // 文本消息  
  36. if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_TEXT)) {  
  37. resqContext = "您发送了文本消息";  
  38. }  
  39.   
  40.   
  41. // 图片消息  
  42. if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_IMAGE)) {  
  43. resqContext = "您发送了图片消息";  
  44. }  
  45.   
  46. //事件消息  
  47. if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_EVENT)) {  
  48. //获取事件类型  
  49. String eventType = map.get("EVENT");  
  50.   
  51. if(eventType.equals(MessageUtils.EVENT_TYPE_SUBSCRIBE)){  
  52. //关注  
  53. resqContext = "谢谢你的关注";  
  54. }  
  55.   
  56. if(eventType.equals(MessageUtils.EVENT_TYPE_UNSUBSCRIBE)){  
  57. //TODO取消关注  
  58.   
  59. }  
  60.   
  61. if(eventType.equals(MessageUtils.EVENT_TYPE_CLICK)){  
  62. //TODO自定义菜单  
  63.   
  64. }  
  65.   
  66. if(eventType.equals(MessageUtils.EVENT_TYPE_SCAN)){  
  67. //TODO扫描二维码  
  68.   
  69. }  
  70. }  
  71.   
  72. //设置返回内容  
  73. responseText.setContent(resqContext);  
  74.   
  75. //将对象转为xml数据  
  76. resqXml = MessageUtils.messageToXml(responseText);  
  77.   
  78.   
  79.   
  80. return resqXml;  
  81. }  
  82.   
  83.   
  84. }  




四:在post方法中调用CoreService处理业务


  1. /** 
  2. * 消息的处理和响应 
  3. * @param request 
  4. * @param response 
  5. * @throws Exception  
  6. */  
  7. @RequestMapping(value="handle",method=RequestMethod.POST)  
  8. public void messageHandle(HttpServletRequest request,HttpServletResponse response) throws Exception{  
  9.        //将请求、响应的编码设置为utf-8  
  10. request.setCharacterEncoding("UTF-8");  
  11. response.setCharacterEncoding("UTF-8");  
  12.   
  13. //调用核心业务逻辑  
  14. String respXml = CoreService.processRequest(request);  
  15.   
  16. //响应消息  
  17. PrintWriter out = response.getWriter();  
  18. out.print(respXml);  
  19. out.close();  
  20.   
  21.   

文末福利:

福利一:前端,Java,产品经理,微信小程序,Python等10G资源合集大放送:jianshu.com/p/e8197d4d9

福利二:微信小程序入门与实战全套详细视频教程。


【领取方法】

关注 【编程微刊】微信公众号:

回复【小程序demo】一键领取130个微信小程序源码demo资源。

回复【领取资源】一键领取前端,Java,产品经理,微信小程序,Python等资源合集10G资源大放送。





原文作者:祈澈姑娘
原文链接:jianshu.com/u/05f416aef
创作不易,转载请告知

90后前端妹子,爱编程,爱运营,爱折腾。
坚持总结工作中遇到的技术问题,坚持记录工作中所所思所见,欢迎大家一起探讨交流。


原文地址:https://www.cnblogs.com/ting6/p/9725604.html