在前幾節文章中咱們講述了微信公衆號環境的搭建、如何接入微信公衆平臺、以及微信服務器請求消息,響應消息,事件消息以及工具處理類的封裝;接下來咱們重點說一下-微信服務器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 }
將響應消息轉換成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 }
咱們在接收微信發送的消息時,須要根據消息的不一樣類別來進行處理,這是咱們就須要一個工具類來處理事件類型的消息和普通消息類型的工具類: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 }
經過查看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 }
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 }
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 }
這個時候咱們須要咱們來完善消息入口【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 }
好了,如今讓咱們啓動本地服務來測試一下吧,打開微信測試號管理:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login,配置能夠參考:Java開發微信公衆號(二)---開啓開發者模式,接入微信公衆平臺開發 和 Java開發微信公衆號(一)---初識微信公衆號以及環境搭建;
掃描二維碼,關注你的測試公衆號:而後你能夠發送消息來測試
效果以下:
若是在操做過程當中有問題,歡迎隨時討論^.^
其餘文章關聯
(一)Java開發微信公衆號(一)---初識微信公衆號以及環境搭建
(二)Java開發微信公衆號(二)---開啓開發者模式,接入微信公衆平臺開發