Java開發微信公衆號(四)---微信服務器post消息體的接收及消息的處理

      在前幾節文章中咱們講述了微信公衆號環境的搭建如何接入微信公衆平臺、以及微信服務器請求消息,響應消息,事件消息以及工具處理類的封裝;接下來咱們重點說一下-微信服務器post消息體的接收及消息的處理,這個post方法定義在如何接入微信公衆平臺的【controller】中。html

/**
     * 接收微信消息處理並作分發
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(method=RequestMethod.POST)
    public void post(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // TODO 消息的接收、處理、響應

    }

post方法有兩個參數:java

   1.request中封裝了請求相關的全部內容,能夠從request中取出微信服務器發來的消息;web

   2.response咱們能夠對接收到的消息進行響應,即發送消息。正則表達式

 由於微信服務器發送過來的是xml格式的消息,因此咱們能夠採用 開源框架dom4j去解析xml 。在pom.xml文件中加:sql

<dependency>
    <groupId>org.apache.directory.studio</groupId>
    <artifactId>org.dom4j.dom4j</artifactId>
    <version>1.6.1</version>
</dependency>

處理xml格式消息的方法 前面也提到過的工具類MessageType中:apache

 1 /**
 2      * @Title parseXml
 3      * @Description 將用戶的xml消息提取成map key value 類型
 4      * @param request
 5      * @param response
 6      * @return
 7      * @throws Exception
 8      */
 9     public static Map<String, String> parseXml(HttpServletRequest request, HttpServletResponse response)
10             throws Exception {
11         // 將解析結果存儲在HashMap中
12         Map<String, String> map = new HashMap<String, String>();
13         // 從request中取得輸入流
14         InputStream inputStream = request.getInputStream();
15         // 讀取輸入流
16         SAXReader reader = new SAXReader();
17         Document document = reader.read(inputStream);
18         // 獲得xml根元素
19         Element root = document.getRootElement();
20         // 獲得根元素的全部子節點
21         List<Element> elementList = root.elements();
22         // 遍歷全部子節點
23         for (Element e : elementList) {
24             map.put(e.getName(), e.getText());
25         }
26         // 釋放資源
27         inputStream.close();
28         inputStream = null;
29         return map;
30     }
View Code

 將響應消息轉換成xml格式返回給微信服務器,我是直接把各類消息類型封裝成xml文件,大家也能夠利用xstream-1.3.1.jar 或 xmlpull-1.1.3.1.jar來實現Java類到xml的轉換數組

構建回覆消息ReplyMessageUtil類服務器

  1 package com.webchat.util.weixin;
  2 
  3 import java.io.Serializable;
  4 
  5 import com.webchat.entity.output.Articles;
  6 import com.webchat.entity.output.ImageOutputMessage;
  7 import com.webchat.entity.output.MusicOutputMessage;
  8 import com.webchat.entity.output.NewsOutputMessage;
  9 import com.webchat.entity.output.TextMessage;
 10 import com.webchat.entity.output.VideoOutPutMessage;
 11 import com.webchat.entity.output.VoiceOutputMessage;
 12 
 13 /**
 14  * 構建回覆消息
 15  * 
 16  * @author Administrator
 17  *
 18  */
 19 public class ReplyMessageUtil implements Serializable {
 20     private static final long serialVersionUID = 1L;
 21     /**
 22      * <xml> <ToUserName><![CDATA[toUser]]></ToUserName>
 23      * <FromUserName><![CDATA[fromUser]]></FromUserName>
 24      * <CreateTime>12345678</CreateTime> <MsgType><![CDATA[news]]></MsgType>
 25      * <ArticleCount>2</ArticleCount> <Articles> <item>
 26      * <Title><![CDATA[title1]]></Title>
 27      * <Description><![CDATA[description1]]></Description>
 28      * <PicUrl><![CDATA[picurl]]></PicUrl> <Url><![CDATA[url]]></Url> </item>
 29      * <item> <Title><![CDATA[title]]></Title>
 30      * <Description><![CDATA[description]]></Description>
 31      * <PicUrl><![CDATA[picurl]]></PicUrl> <Url><![CDATA[url]]></Url> </item>
 32      * </Articles> </xml>
 33      * 
 34      * @Title sendImageTextMessage
 35      * @Description 回覆圖文消息
 36      * @param message
 37      * @return
 38      */
 39     public static String sendImageTextMessage(NewsOutputMessage message) {
 40         StringBuffer sb = new StringBuffer();
 41         sb.append("<xml>");
 42         sb.append("<ToUserName><![CDATA[" + message.getToUserName() + "]]></ToUserName>");
 43         sb.append("<FromUserName><![CDATA[" + message.getFromUserName() + "]]></FromUserName>");
 44         sb.append("<CreateTime>" + message.getCreateTime() + "</CreateTime>");
 45         sb.append("<MsgType><![CDATA[" + MessageType.IMAGE_TEXT_MESSAGE + "]]></MsgType>");
 46         sb.append("<ArticleCount>" + message.getArticleCount() + "</ArticleCount>");
 47         sb.append("<Articles> ");
 48         for (Articles article : message.getArticles()) {
 49             sb.append("<item>");
 50             if(article.getTitle()!=null && article.getTitle()!=""){
 51                 sb.append("<Title><![CDATA[").append(article.getTitle()).append("]]></Title>");
 52             }
 53             if(article.getDescription()!=null && article.getDescription()!=""){
 54                 sb.append("<Description><![CDATA[").append(article.getDescription()).append("]]></Description>");
 55             }
 56             if(article.getPicUrl()!=null && article.getPicUrl()!=""){
 57                 sb.append("<PicUrl><![CDATA[").append(article.getPicUrl()).append("]]></PicUrl>");
 58             }
 59             if(article.getUrl()!=null && article.getUrl()!=""){
 60                 sb.append("<Url><![CDATA[").append(article.getUrl()).append("]]></Url>");
 61             }
 62             sb.append("</item>");
 63         }
 64         sb.append("</Articles>");
 65         sb.append("</xml>");
 66         return sb.toString();
 67     }
 68 
 69     /**
 70      * <xml> <ToUserName><![CDATA[toUser]]></ToUserName>
 71      * <FromUserName><![CDATA[fromUser]]></FromUserName>
 72      * <CreateTime>12345678</CreateTime> <MsgType><![CDATA[music]]></MsgType>
 73      * <Music> <Title><![CDATA[TITLE]]></Title>
 74      * <Description><![CDATA[DESCRIPTION]]></Description>
 75      * <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
 76      * <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
 77      * <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId> </Music> </xml>
 78      * 
 79      * @Title sendMusicMessage
 80      * @Description 回覆音樂消息
 81      * @param message
 82      * @return
 83      */
 84     public static String sendMusicMessage(MusicOutputMessage message) {
 85         StringBuffer sb = new StringBuffer();
 86         sb.append("<xml>");
 87         sb.append("<ToUserName><![CDATA[" + message.getToUserName() + "]]></ToUserName>");
 88         sb.append("<FromUserName><![CDATA[" + message.getFromUserName() + "]]></FromUserName>");
 89         sb.append("<CreateTime>" + message.getCreateTime() + "</CreateTime>");
 90         sb.append("<MsgType><![CDATA[" + MessageType.MUSIC_MESSAGE + "]]></MsgType>");
 91         sb.append("<Music>");
 92         if (message.getMusic().getTitle() != null && !"".equals(message.getMusic().getTitle())) {
 93             sb.append("<Title><![CDATA[" + message.getMusic().getTitle() + "]]></Title>");
 94         }
 95         if (message.getMusic().getDescription() != null && !"".equals(message.getMusic().getDescription())) {
 96             sb.append("<Description><![CDATA[" + message.getMusic().getDescription() + "]]></Description>");
 97         }
 98         if (message.getMusic().getMusicUrl() != null && !"".equals(message.getMusic().getMusicUrl())) {
 99             sb.append("<MusicUrl><![CDATA[" + message.getMusic().getMusicUrl() + "]]></MusicUrl>");
100         }
101         if (message.getMusic().getHQMusicUrl() != null && !"".equals(message.getMusic().getHQMusicUrl())) {
102             sb.append("<HQMusicUrl><![CDATA[" + message.getMusic().getHQMusicUrl() + "]]></HQMusicUrl>");
103         }
104 
105         sb.append("<ThumbMediaId><![CDATA[" + message.getMusic().getThumbMediaId() + "]]></ThumbMediaId>");
106         sb.append("</Music>");
107         sb.append("</xml>");
108         return sb.toString();
109     }
110 
111     /**
112      * <xml> <ToUserName><![CDATA[toUser]]></ToUserName>
113      * <FromUserName><![CDATA[fromUser]]></FromUserName>
114      * <CreateTime>12345678</CreateTime> <MsgType><![CDATA[video]]></MsgType>
115      * <Video> <MediaId><![CDATA[media_id]]></MediaId>
116      * <Title><![CDATA[title]]></Title>
117      * <Description><![CDATA[description]]></Description> </Video> </xml>
118      * 
119      * @Title sendVideoMessage
120      * @Description 回覆視頻消息
121      * @param message
122      * @return
123      */
124     public static String sendVideoMessage(VideoOutPutMessage message) {
125         StringBuffer sb = new StringBuffer();
126         sb.append("<xml>");
127         sb.append("<ToUserName><![CDATA[" + message.getToUserName() + "]]></ToUserName>");
128         sb.append("<FromUserName><![CDATA[" + message.getFromUserName() + "]]></FromUserName>");
129         sb.append("<CreateTime>" + message.getCreateTime() + "</CreateTime>");
130         sb.append("<MsgType><![CDATA[" + MessageType.VIDEO_MESSAGE + "]]></MsgType>");
131         sb.append("<Video>");
132         sb.append("<MediaId><![CDATA[" + message.getVideo().getMediaId() + "]]></MediaId>");
133         if (message.getVideo().getTitle() != null && !"".equals(message.getVideo().getTitle())) {
134             sb.append("<Title><![CDATA[" + message.getVideo().getTitle() + "]]></Title>");
135         }
136         if (message.getVideo().getDescription() != null && !"".equals(message.getVideo().getDescription())) {
137             sb.append("<Description><![CDATA[" + message.getVideo().getDescription() + "]]></Description>");
138         }
139         sb.append("</Video>");
140         sb.append("</xml>");
141         return sb.toString();
142     }
143 
144     /**
145      * <xml> <ToUserName><![CDATA[toUser]]></ToUserName>
146      * <FromUserName><![CDATA[fromUser]]></FromUserName>
147      * <CreateTime>12345678</CreateTime> <MsgType><![CDATA[voice]]></MsgType>
148      * <Voice> <MediaId><![CDATA[media_id]]></MediaId> </Voice> </xml>
149      * @Title sendVoiceMessage
150      * @Description 回覆語音消息
151      * @param message
152      * @return
153      */
154     public static String sendVoiceMessage(VoiceOutputMessage message) {
155         StringBuffer sb = new StringBuffer();
156         sb.append("<xml>");
157         sb.append("<ToUserName><![CDATA[" + message.getToUserName() + "]]></ToUserName>");
158         sb.append("<FromUserName><![CDATA[" + message.getFromUserName() + "]]></FromUserName>");
159         sb.append("<CreateTime>" + message.getCreateTime() + "</CreateTime>");
160         sb.append("<MsgType><![CDATA[" + MessageType.VOICE_MESSAGE + "]]></MsgType>");
161         sb.append("<Voice>");
162         sb.append("<MediaId><![CDATA[" + message.getVoice().getMediaId() + "]]></MediaId>");
163         sb.append("</Voice>");
164         sb.append("</xml>");
165         return sb.toString();
166     }
167 
168     /**
169      * <xml> <ToUserName><![CDATA[toUser]]></ToUserName>
170      * <FromUserName><![CDATA[fromUser]]></FromUserName>
171      * <CreateTime>12345678</CreateTime> <MsgType><![CDATA[image]]></MsgType>
172      * <Image> <MediaId><![CDATA[media_id]]></MediaId> </Image> </xml>
173      * @Title sendImageMessage
174      * @Description 回覆圖片消息
175      * @param message
176      */
177     public static String sendImageMessage(ImageOutputMessage message) {
178         StringBuffer sb = new StringBuffer();
179         sb.append("<xml>");
180         sb.append("<ToUserName><![CDATA[" + message.getToUserName() + "]]></ToUserName>");
181         sb.append("<FromUserName><![CDATA[" + message.getFromUserName() + "]]></FromUserName>");
182         sb.append("<CreateTime>" + message.getCreateTime() + "</CreateTime>");
183         sb.append("<MsgType><![CDATA[" + MessageType.IMAGE_MESSAGE + "]]></MsgType>");
184         sb.append("<Image>");
185         sb.append("<MediaId><![CDATA[" + message.getImage().getMediaId() + "]]></MediaId>");
186         sb.append("</Image>");
187         sb.append("</xml>");
188         return sb.toString();
189     }
190     /**
191      * <xml> <ToUserName>< ![CDATA[toUser] ]></ToUserName> <FromUserName><
192      * ![CDATA[fromUser] ]></FromUserName> <CreateTime>12345678</CreateTime>
193      * <MsgType>< ![CDATA[text] ]></MsgType> <Content>< ![CDATA[你好] ]></Content>
194      * </xml> sendTextMessage
195      * @param message
196      * @return
197      */
198     public static String sendTextMessage(TextMessage message) {
199         StringBuffer sb = new StringBuffer();
200         sb.append("<xml>");
201         sb.append("<ToUserName><![CDATA[" + message.getToUserName() + "]]></ToUserName>");
202         sb.append("<FromUserName><![CDATA[" + message.getFromUserName() + "]]></FromUserName>");
203         sb.append("<CreateTime>" + message.getCreateTime() + "</CreateTime>");
204         sb.append("<MsgType><![CDATA[" + MessageType.TEXT_MESSAGE + "]]></MsgType>");
205         sb.append("<Content><![CDATA[" + message.getContent() + "]]></Content>");
206         sb.append("</xml>");
207         return sb.toString();
208     }
209 }
View Code

 咱們在接收微信發送的消息時,須要根據消息的不一樣類別來進行處理,這是咱們就須要一個工具類來處理事件類型的消息和普通消息類型的工具類:WebChatService微信

  1 package com.webchat.service;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Date;
  5 import java.util.HashMap;
  6 import java.util.List;
  7 import java.util.Map;
  8 
  9 import com.webchat.entity.output.Articles;
 10 import com.webchat.entity.output.NewsOutputMessage;
 11 import com.webchat.entity.output.TextMessage;
 12 import com.webchat.util.weixin.MessageType;
 13 import com.webchat.util.weixin.ReplyMessageUtil;
 14 import com.webchat.util.weixin.utils.XmlUtil;
 15 
 16 /**
 17  * 處理接收信息和回覆消息的服務類接口
 18  * 
 19  * @author Administrator
 20  *
 21  */
 22 public class WebChatService {
 23     // 處理微信發來的請求 map 消息業務處理分發
 24     public static String parseMessage(Map<String, String> map) {
 25         String respXml = null;
 26         try {
 27             // 發送方賬號
 28             String fromUserName = map.get("FromUserName");
 29             // 開發者微信號
 30             String toUserName = map.get("ToUserName");
 31             // 取得消息類型
 32             String MsgType = map.get("MsgType");
 33             // 發現直接把要返回的信息直接封裝成replyMap集合,而後轉換成 xml文件,是否是實體類能夠不用了
 34             Map<String, String> replyMap = new HashMap<String, String>();
 35             replyMap.put("ToUserName", fromUserName);
 36             replyMap.put("FromUserName", toUserName);
 37             replyMap.put("CreateTime", String.valueOf(new Date().getTime()));
 38             if (MsgType.equals(MessageType.TEXT_MESSAGE)) {
 39                 // 封裝文本返回消息
 40                 TextMessage textMessage = new TextMessage();
 41                 textMessage.setToUserName(fromUserName);
 42                 textMessage.setFromUserName(toUserName);
 43                 textMessage.setCreateTime(new Date().getTime());
 44                 textMessage.setContent("您發送的是文本消息");
 45                 textMessage.getMsgType();
 46                 // respXml = ReplyMessageUtil.sendTextMessage(textMessage);
 47 
 48                 // 用map集合封裝
 49                 replyMap.put("MsgType", MessageType.RESP_MESSAGE_TYPE_TEXT);
 50                 replyMap.put("Content", "您發送的是文本消息");
 51                 respXml = XmlUtil.xmlFormat(replyMap, true);
 52             } else if (MsgType.equals(MessageType.IMAGE_MESSAGE)) {
 53                 // 這裏回覆圖片 或者圖文消息 以圖文消息爲例
 54                 NewsOutputMessage message = new NewsOutputMessage();
 55                 message.setToUserName(fromUserName);
 56                 message.setFromUserName(toUserName);
 57                 message.setCreateTime(new Date().getTime());
 58                 message.getMsgType();
 59 
 60                 Articles article = new Articles();
 61                 article.setDescription("圖文消息 "); // 圖文消息的描述
 62                 article.setPicUrl("https://p4.ssl.cdn.btime.com/dmfd/192_108_/t019d0b65e33000f8a0.jpg?size=458x240"); // 圖文消息圖片地址
 63                 article.setTitle("圖文消息 "); // 圖文消息標題
 64                 article.setUrl("http://www.baidu.com"); // 圖文 url 連接
 65                 List<Articles> list = new ArrayList<Articles>();
 66                 list.add(article);// 這裏發送的是單圖文,若是須要發送多圖文則在這裏 list 中加入多個
 67                                     // Articles!
 68 
 69                 message.setArticleCount(list.size());
 70                 message.setArticles(list);
 71                 respXml = ReplyMessageUtil.sendImageTextMessage(message);
 72             } else if (MsgType.equals(MessageType.VOICE_MESSAGE)) {
 73                 // 如下方式根據須要來操做
 74                 replyMap.put("MsgType", MessageType.RESP_MESSAGE_TYPE_TEXT);
 75                 replyMap.put("Content", "您發送的是語音消息");
 76                 respXml = XmlUtil.xmlFormat(replyMap, true);
 77             } else if (MsgType.equals(MessageType.VIDEO_MESSAGE)) {
 78                 replyMap.put("MsgType", MessageType.RESP_MESSAGE_TYPE_TEXT);
 79                 replyMap.put("Content", "您發送的是視頻消息");
 80                 respXml = XmlUtil.xmlFormat(replyMap, true);
 81             } else if (MsgType.equals(MessageType.SHORTVIDEO_MESSAGE)) {
 82                 replyMap.put("MsgType", MessageType.RESP_MESSAGE_TYPE_TEXT);
 83                 replyMap.put("Content", "您發送的是小視頻消息");
 84                 respXml = XmlUtil.xmlFormat(replyMap, true);
 85             } else if (MsgType.equals(MessageType.POSOTION_MESSAGE)) {
 86                 replyMap.put("MsgType", MessageType.RESP_MESSAGE_TYPE_TEXT);
 87                 replyMap.put("Content", "您發送的是地理位置消息");
 88                 respXml = XmlUtil.xmlFormat(replyMap, true);
 89             } else if (MsgType.equals(MessageType.LINK_MESSAGE)) {
 90                 replyMap.put("MsgType", MessageType.RESP_MESSAGE_TYPE_TEXT);
 91                 replyMap.put("Content", "您發送的是連接消息");
 92                 respXml = XmlUtil.xmlFormat(replyMap, true);
 93             }
 94         } catch (Exception e) {
 95             e.printStackTrace();
 96         }
 97         return respXml;
 98     }
 99 
100     // 事件消息業務分發
101     public static String parseEvent(Map<String, String> map) {
102         String respXml = null;
103         try {
104             // 發送方賬號
105             String fromUserName = map.get("FromUserName");
106             // 開發者微信號
107             String toUserName = map.get("ToUserName");
108             // 取得消息類型
109             String MsgType = map.get("MsgType");
110             //獲取事件類型
111             String eventType = map.get("Event");
112             
113             // 發現直接把要返回的信息直接封裝成replyMap集合,而後轉換成 xml文件,是否是實體類能夠不用了
114             Map<String, String> replyMap = new HashMap<String, String>();
115             replyMap.put("ToUserName", fromUserName);
116             replyMap.put("FromUserName", toUserName);
117             replyMap.put("CreateTime", String.valueOf(new Date().getTime()));
118             if (eventType.equals(MessageType.EVENT_TYPE_SUBSCRIBE)) {// 關注
119                 // 用map集合封裝
120                 replyMap.put("MsgType", MessageType.RESP_MESSAGE_TYPE_TEXT);
121                 replyMap.put("Content", MessageType.menuText());
122                 respXml = XmlUtil.xmlFormat(replyMap, true);
123             }
124             if (eventType.equals(MessageType.EVENT_TYPE_UNSUBSCRIBE)) {// 取消關注
125 
126             }
127             if (eventType.equals(MessageType.EVENT_TYPE_SCAN)) {// 用戶已關注時的掃描帶參數二維碼
128 
129             }
130             if (eventType.equals(MessageType.EVENT_TYPE_LOCATION)) {// 上報地理位置
131 
132             }
133             if (eventType.equals(MessageType.EVENT_TYPE_CLICK)) {// 自定義菜單
134 
135             }
136         } catch (Exception e) {
137             e.printStackTrace();
138         }
139         return respXml;
140     }
141 }
View Code

 經過查看WebChatService工具類,你會發現我裏面既有經過回覆消息實體類 獲取回覆信息而後調用ReplyMessageUtil類中對應的方法來返回信息,還有經過集合Map(replyMap)key,value的方法來添加數據,而後調用XmlUtil.java 的xmlFormat()方法返回消息的,有興趣的能夠都研究下:如今提供須要的工具類和jar文件app

在pom.xml文件加入xmlpull-1.1.3.1.jar

<dependency>
            <groupId>xmlpull</groupId>
            <artifactId>xmlpull</artifactId>
            <version>1.1.3.1</version>
</dependency>

XmlUtil工具類:

 1 package com.webchat.util.weixin.utils;
 2 
 3 import java.io.ByteArrayInputStream;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 import java.util.HashMap;
 7 import java.util.Map;
 8 import java.util.Map.Entry;
 9 
10 import org.xmlpull.v1.XmlPullParser;
11 import org.xmlpull.v1.XmlPullParserException;
12 import org.xmlpull.v1.XmlPullParserFactory;  
13 /**
14  * 封裝和處理xml文件
15  * @author Administrator
16  *
17  */
18 public class XmlUtil {
19 
20     private static final String PREFIX_XML = "<xml>";
21 
22     private static final String SUFFIX_XML = "</xml>";
23 
24     private static final String PREFIX_CDATA = "<![CDATA[";
25 
26     private static final String SUFFIX_CDATA = "]]>";
27 
28     /**
29      * 轉化成xml, 單層無嵌套
30      * 
31      * @param map
32      * @param isAddCDATA  ture 加CDATA標籤  false 不加CDATA標籤
33      * @return
34      */
35     public static String xmlFormat(Map<String, String> parm, boolean isAddCDATA) {
36 
37         StringBuffer strbuff = new StringBuffer(PREFIX_XML);
38         if (CollectionUtil.isNotEmpty(parm)) {
39             for (Entry<String, String> entry : parm.entrySet()) {
40                 strbuff.append("<").append(entry.getKey()).append(">");
41                 if (isAddCDATA) {
42                     strbuff.append(PREFIX_CDATA);
43                     if (StringUtil.isNotEmpty(entry.getValue())) {
44                         strbuff.append(entry.getValue());
45                     }
46                     strbuff.append(SUFFIX_CDATA);
47                 } else {
48                     if (StringUtil.isNotEmpty(entry.getValue())) {
49                         strbuff.append(entry.getValue());
50                     }
51                 }
52                 strbuff.append("</").append(entry.getKey()).append(">");
53             }
54         }
55         return strbuff.append(SUFFIX_XML).toString();
56     }
57 
58     /**
59      * 解析xml
60      * 
61      * @param xml
62      * @return
63      * @throws XmlPullParserException
64      * @throws IOException
65      */
66     public static Map<String, String> xmlParse(String xml) throws XmlPullParserException, IOException {
67         Map<String, String> map = null;
68         if (StringUtil.isNotEmpty(xml)) {
69             InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
70             XmlPullParser pullParser = XmlPullParserFactory.newInstance().newPullParser();
71             pullParser.setInput(inputStream, "UTF-8"); // 爲xml設置要解析的xml數據
72             int eventType = pullParser.getEventType();
73 
74             while (eventType != XmlPullParser.END_DOCUMENT) {
75                 switch (eventType) {
76                 case XmlPullParser.START_DOCUMENT:
77                     map = new HashMap<String, String>();
78                     break;
79                 case XmlPullParser.START_TAG:
80                     String key = pullParser.getName();
81                     if (key.equals("xml"))
82                         break;
83                     String value = pullParser.nextText().trim();
84                     map.put(key, value);
85                     break;
86                 case XmlPullParser.END_TAG:
87                     break;
88                 }
89                 eventType = pullParser.next();
90             }
91         }
92         return map;
93     }
94 }
View Code

XmlUtil 工具類關聯的類CollectionUtil 和StringUtil

  1 package com.webchat.util.weixin.utils;
  2 
  3 import java.util.HashSet;
  4 import java.util.Set;
  5 import java.util.UUID;
  6 import java.util.regex.Matcher;
  7 import java.util.regex.Pattern;
  8 
  9 /**
 10  * String工具類
 11  */
 12 public class StringUtil {
 13 
 14     private StringUtil() {
 15         super();
 16     }
 17 
 18     /**
 19      * 出去null和""
 20      * @param src
 21      * @return
 22      */
 23     public static String formatNull(String src) {
 24         return (src == null || "null".equals(src)) ? "" : src;
 25     }
 26 
 27     /**
 28      * 判斷字符串是否爲空的正則表達式,空白字符對應的unicode編碼
 29      */
 30     private static final String EMPTY_REGEX = "[\\s\\u00a0\\u2007\\u202f\\u0009-\\u000d\\u001c-\\u001f]+";
 31 
 32     /**
 33      * 驗證字符串是否爲空
 34      * 
 35      * @param input
 36      * @return
 37      */
 38     public static boolean isEmpty(String input) {
 39         return input == null || input.equals("") || input.matches(EMPTY_REGEX);
 40     }
 41     
 42     public static boolean isNotEmpty(String input){
 43         return !isEmpty(input);
 44     }
 45 
 46     private static final String NUM_REG = "(\\+|\\-)?\\s*\\d+(\\.\\d+)?";
 47 
 48     /**
 49      * 判斷是否數字
 50      * 
 51      * @param str
 52      * @return
 53      */
 54     public static boolean isNumber(String str) {
 55         if (isEmpty(str)) {
 56             return false;
 57         }
 58 
 59         if (str.trim().matches(NUM_REG)) {
 60             return true;
 61         }
 62 
 63         return false;
 64     }
 65 
 66     /**
 67      * 判斷是否包含有亂碼的數據,若是字符串中包含有替換字符就認爲是亂碼
 68      * 
 69      * @param str
 70      * @return
 71      */
 72     public static boolean containUnreadableCode(String str) {
 73         return contain(str, "\\ufffd");
 74     }
 75 
 76     /**
 77      * 判讀是否包含數字
 78      * 
 79      * @param str
 80      * @return
 81      */
 82     public static boolean containNumber(String str) {
 83         return contain(str, "\\d");
 84     }
 85 
 86     /**
 87      * 判斷是否包含a-zA-Z_0-9
 88      * 
 89      * @param str
 90      * @return
 91      */
 92     public static boolean containWord(String str) {
 93         return contain(str, "\\w");
 94     }
 95 
 96     /**
 97      * 是否包含有標點符號
 98      * 
 99      * @param str
100      * @return
101      */
102     public static boolean containPunct(String str) {
103         return contain(str, PUNCT_REG);
104     }
105 
106     public static boolean contain(String str, String regex) {
107         if (isEmpty(str) || isEmpty(regex)) {
108             return false;
109         }
110 
111         if (str.trim().matches(regex)) {
112             return true;
113         }
114 
115         Pattern pattern = Pattern.compile(regex);
116         Matcher matcher = pattern.matcher(str);
117         if (matcher.find()) {
118             return true;
119         }
120 
121         return false;
122     }
123 
124     /**
125      * 替換全部的(不區分大小寫)
126      * 
127      * @param input
128      * @param regex
129      * @param replacement
130      * @return
131      */
132     public static String replaceAll(String input, String regex,
133             String replacement) {
134         return Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matcher(input)
135                 .replaceAll(replacement);
136     }
137 
138     /**
139      * 移除全部的空格
140      * 
141      * @param text
142      * @return
143      */
144     public static String removeAllSpace(String text) {
145         if (isEmpty(text)) {
146             return text;
147         }
148 
149         return text.replaceAll("[ ]+", "");
150     }
151 
152     private static final String PUNCT_REG = "[^a-zA-Z0-9\\u4e00-\\u9fa5]";
153 
154     /**
155      * 移除字符串中的全部的中英文標點符號
156      * 
157      * @param str
158      * @return
159      */
160     public static String removeAllPunct(String str) {
161         if (isEmpty(str)) {
162             return str;
163         }
164 
165         return str.replaceAll(PUNCT_REG, "");
166     }
167 
168     /**
169      * 計算str中包含多少個子字符串sub
170      * 
171      * @param str
172      * @param sub
173      * @return
174      */
175     public static int countMatches(String str, String sub) {
176         if (isEmpty(str) || isEmpty(sub)) {
177             return 0;
178         }
179 
180         int count = 0;
181         int idx = 0;
182         while ((idx = str.indexOf(sub, idx)) != -1) {
183             count++;
184             idx += sub.length();
185         }
186 
187         return count;
188     }
189 
190     /**
191      * 得到源字符串的一個子字符串
192      * 
193      * @param str
194      *            :源字符串
195      * @param beginIndex
196      *            :開始索引(包括)
197      * @param endIndex
198      *            :結束索引(不包括)
199      * @return
200      */
201     public static String substring(String str, int beginIndex, int endIndex) {
202         if (isEmpty(str)) {
203             return str;
204         }
205 
206         int length = str.length();
207 
208         if (beginIndex >= length || endIndex <= 0 || beginIndex >= endIndex) {
209             return null;
210         }
211 
212         if (beginIndex < 0) {
213             beginIndex = 0;
214         }
215         if (endIndex > length) {
216             endIndex = length;
217         }
218 
219         return str.substring(beginIndex, endIndex);
220     }
221 
222     /**
223      * 計算str中包含子字符串sub所在位置的前一個字符或者後一個字符和sub所組成的新字符串
224      * 
225      * @param str
226      * @param sub
227      * @return
228      */
229     public static Set<String> substring(String str, String sub) {
230         if (isEmpty(str) || isEmpty(sub)) {
231             return null;
232         }
233 
234         Set<String> result = new HashSet<String>();
235         int idx = 0;
236         while ((idx = str.indexOf(sub, idx)) != -1) {
237             String temp = substring(str, idx - 1, idx + sub.length());
238             if (!isEmpty(temp)) {
239                 temp = removeAllPunct(temp);
240                 if (!sub.equalsIgnoreCase(temp) && !containWord(temp)) {
241                     result.add(temp);
242                 }
243 
244             }
245 
246             temp = substring(str, idx, idx + sub.length() + 1);
247             if (!isEmpty(temp)) {
248                 temp = removeAllPunct(temp);
249                 if (!sub.equalsIgnoreCase(temp) && !containWord(temp)) {
250                     result.add(temp);
251                 }
252             }
253 
254             idx += sub.length();
255         }
256 
257         return result;
258     }
259 
260     /**
261      * 過濾掉XML中沒法解析的非法字符
262      * 
263      * @param content
264      * @return
265      */
266     public static String wrapXmlContent(String content) {
267         if (isEmpty(content)) {
268             return "";
269         }
270 
271         StringBuilder result = new StringBuilder();
272 
273         for (int i = 0; i < content.length(); i++) {
274             char ch = content.charAt(i);
275             if ((ch == '\t') || (ch == '\n') || (ch == '\r')
276                     || ((ch >= ' ') && (ch <= 55295))
277                     || ((ch >= 57344) && (ch <= 65533))
278                     || ((ch >= 65536) && (ch <= 1114111))) {
279                 result.append(ch);
280             }
281         }
282 
283         return result.toString();
284     }
285 
286     /**
287      * 判斷字符串的長度
288      * 
289      * @param str
290      * @return
291      */
292     public static boolean overLength(String str) {
293         if (isEmpty(str)) {
294             return false;
295         }
296 
297         return str.length() > 1 ? true : false;
298     }
299 
300     /**
301      * 字符串中含有特殊字符的處理
302      * 
303      * @param str
304      * @return
305      */
306     public static String specialStr(String str) {
307         str = str.replaceAll("[^\\u4e00-\\u9fa5 | 0-9| a-zA-Z | \\.]+", " ")
308                 .replaceAll("[\\.]{2,}", " ").trim();
309         return str;
310     }
311 
312     /**
313      * 將特殊符號去掉,可是保留空格
314      * 
315      * @param str
316      * @return
317      */
318     public static String replaceInValidateChar(String str) {
319         return str.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5\\s+]", " ");
320     }
321 
322     /**
323      * 返回字符串對應的unicode編碼
324      * 
325      * @param str
326      * @return
327      */
328     public static String[] toHexString(String str) {
329         char[] chars = str.toCharArray();
330 
331         String[] result = new String[chars.length];
332 
333         for (int i = 0; i < chars.length; i++) {
334             result[i] = Integer.toHexString((int) chars[i]);
335         }
336 
337         return result;
338     }
339 
340     public static String getUuid() {
341         return UUID.randomUUID().toString();
342     }
343     
344     public static boolean isUrl(String src) {
345         String regex = "http[s]?:\\/\\/([\\w-]+\\.[\\w-]+)(\\.[\\w-])+(:\\d{2,10})?.*";
346         Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
347         Matcher matcher = pattern.matcher(src);
348         return matcher.matches();
349     }
350     
351     /**
352      * sql 查詢轉義
353      * @param str
354      * @return
355      */
356     public static String escapeSql(String str){
357         if (StringUtil.isNotEmpty(str)) {
358             StringBuffer strbuff = new StringBuffer();
359             for (String s : str.split("")) {
360                 if (s.equals("%") || s.equals("_") || s.equals("\\")) {
361                     strbuff.append("\\");
362                 }
363                 strbuff.append(s);
364             }
365             return strbuff.toString();
366         }
367         return str;
368     }
369 }
View Code
 1 package com.webchat.util.weixin.utils;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Collection;
 5 import java.util.List;
 6 import java.util.Map;
 7 
 8 public class CollectionUtil {
 9 
10     private CollectionUtil() {
11         super();
12     }
13 
14     // 判斷一個集合是否爲空
15     public static <T> boolean isEmpty(Collection<T> col) {
16         if (col == null || col.isEmpty()) {
17             return true;
18         }
19 
20         return false;
21     }
22 
23     // 判斷一個集合是否不爲空
24     public static <T> boolean isNotEmpty(Collection<T> col) {
25         return !isEmpty(col);
26     }
27 
28     // 判斷Map是否爲空
29     public static <K, V> boolean isEmpty(Map<K, V> map) {
30         if (map == null || map.isEmpty()) {
31             return true;
32         }
33 
34         return false;
35     }
36 
37     // 判斷Map是否不爲空爲空
38     public static <K, V> boolean isNotEmpty(Map<K, V> map) {
39         return !isEmpty(map);
40     }
41 
42     // 去除list中的重複數據
43     public static <T> List<T> removeRepeat(List<T> list) {
44         if (isEmpty(list)) {
45             return list;
46         }
47 
48         List<T> result = new ArrayList<T>();
49         for (T e : list) {
50             if (!result.contains(e)) {
51                 result.add(e);
52             }
53         }
54 
55         return result;
56     }
57 
58     // 將集合轉換爲String數組
59     public static <T> String[] toArray(List<T> list) {
60         if (isEmpty(list)) {
61             return null;
62         }
63 
64         String[] result = new String[list.size()];
65         for (int i = 0; i < list.size(); i++) {
66             result[i] = String.valueOf(list.get(i));
67         }
68 
69         return result;
70     }
71 
72 }
View Code

 

這個時候咱們須要咱們來完善消息入口【WebChatController.java】中的 post 方法,最終結果以下:

 1 /**
 2      * 接收微信消息處理並作分發
 3      * @param request
 4      * @param response
 5      * @throws Exception
 6      */
 7     @RequestMapping(method=RequestMethod.POST)
 8     public void post(HttpServletRequest request, HttpServletResponse response) throws Exception {
 9         // TODO 消息的接收、處理、響應
10         //消息來源可靠性驗證
11         String signature = request.getParameter("signature");// 微信加密簽名
12         String timestamp = request.getParameter("timestamp");// 時間戳
13         String nonce = request.getParameter("nonce");       // 隨機數
14         //確認這次GET請求來自微信服務器,原樣返回echostr參數內容,則接入生效,成爲開發者成功,不然接入失敗
15         if (!WebChatUtil.checkSignature(signature, timestamp, nonce)) {
16             //消息不可靠,直接返回
17             response.getWriter().write("");
18             return;
19         }
20         //用戶每次向公衆號發送消息、或者產生自定義菜單點擊事件時,響應URL將獲得推送
21         try {
22             response.setCharacterEncoding("UTF-8");
23             response.setContentType("text/xml");
24             //調用parseXml方法解析請求消息
25             Map<String, String> map = MessageType.parseXml(request, response);
26             String MsgType = map.get("MsgType");
27             String xml = null;//處理輸入消息,返回結果的xml
28             if(MessageType.REQ_MESSAGE_TYPE_EVENT.equals(MsgType)){
29                 xml = WebChatService.parseEvent(map);
30             }else{
31                 xml = WebChatService.parseMessage(map);
32             }
33             //返回封裝的xml
34             //System.out.println(xml);
35             response.getWriter().write(xml);
36         } catch (Exception ex) {
37             response.getWriter().write("");
38         }
39     }
View Code

好了,如今讓咱們啓動本地服務來測試一下吧,打開微信測試號管理:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login,配置能夠參考:Java開發微信公衆號(二)---開啓開發者模式,接入微信公衆平臺開發 和 Java開發微信公衆號(一)---初識微信公衆號以及環境搭建

掃描二維碼,關注你的測試公衆號:而後你能夠發送消息來測試

 

效果以下:

 若是在操做過程當中有問題,歡迎隨時討論^.^

 

 

 

 

 

 

 

其餘文章關聯

(一)Java開發微信公衆號(一)---初識微信公衆號以及環境搭建

(二)Java開發微信公衆號(二)---開啓開發者模式,接入微信公衆平臺開發

(三)Java開發微信公衆號(三)---微信服務器請求消息,響應消息,事件消息以及工具處理類的封裝

(四)Java開發微信公衆號(四)---微信服務器post消息體的接收及消息的處理

相關文章
相關標籤/搜索