這篇文章主要為大家詳細介紹了Java微信公眾平台開發第二步,微信伺服器post消息體的接收,具有一定的參考價值,有興趣的小夥伴們可以參考一下
#在上一篇的文章中我們詳細講述瞭如何將我們的應用伺服器和微信騰訊伺服器之間的對接操作,最後接入成功,不知道你有沒有發現在上一篇的【controller】中我定義了一個get方法和一個post方法,但在使用過程中我們就用了get方法,這裡我們就來談談我們預留的post的方法的使用!
當我們在完成了伺服器驗證之後,此後用戶每次向公眾號發送訊息、或者產生自訂選單點擊事件時,開發者填寫的伺服器配置URL將得到微信伺服器推送過來的訊息和事件,然後開發者可以依據自身業務邏輯回應,例如回覆訊息等!透過這句話我們能知道後面所有的微信伺服器和我們應用伺服器之間的溝通都是透過post訊息體來完成的,那麼我們在這裡將講述如何接受微信post的訊息體!
(一)訊息類型和訊息格式
上面有說我們所有的和微信伺服器之間進行溝通基本上都是透過post訊息體完成的,首先我們了解下訊息體的類型,大致類型有兩種:
普通訊息類型:文字訊息、圖片訊息、語音訊息、視訊訊息、小視頻訊息、地理位置訊息、連結訊息
事件訊息類型:追蹤/取消追蹤事件、掃描帶參數二維碼事件、回報地理位置事件、自訂選單事件、點選選單拉取訊息時的事件推播、點選選單跳轉連結時的事件推播
訊息類型:微信服務端推送的所有訊息體的類型格式都是xml格式;
(二)訊息重試機制
微信伺服器在五秒鐘內收不到回應會斷掉連接,並且重新發起請求,總共重試三次。假如伺服器無法保證在五秒內處理並回复,可以直接回复空串,微信伺服器不會對此作任何處理,並且不會發起重試,但是這裡後期可以使用【客服訊息介面】去完成訊息再次推送。
(三)訊息接收處理
在前面我們有說道微信的訊息體是採用xml格式,那麼我在這裡寫了一個MessageUtil去做訊息格式的處理,大致程式碼如下:
package com.cuiyongzhi.wechat.util; 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.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; /** * ClassName: MessageUtil * @Description: 消息工具类 * @author dapengniao * @date 2016年3月7日 上午10:05:04 */ public class MessageUtil { /** * 返回消息类型:文本 */ public static final String RESP_MESSAGE_TYPE_TEXT = "text"; /** * 返回消息类型:音乐 */ public static final String RESP_MESSAGE_TYPE_MUSIC = "music"; /** * 返回消息类型:图文 */ public static final String RESP_MESSAGE_TYPE_NEWS = "news"; /** * 请求消息类型:文本 */ 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_LINK = "link"; /** * 请求消息类型:地理位置 */ public static final String REQ_MESSAGE_TYPE_LOCATION = "location"; /** * 请求消息类型:音频 */ public static final String REQ_MESSAGE_TYPE_VOICE = "voice"; /** * 请求消息类型:推送 */ 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"; /** * 事件类型:CLICK(自定义菜单点击事件) */ public static final String EVENT_TYPE_CLICK = "CLICK"; /** * @Description: 解析微信发来的请求(XML) * @param @param request * @param @return * @param @throws Exception * @author dapengniao * @date 2016年3月7日 上午10:04:02 */ @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; } @SuppressWarnings("unused") private static XStream xstream = new XStream(new XppDriver() { public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { // 对所有xml节点的转换都增加CDATA标记 boolean cdata = true; @SuppressWarnings("rawtypes") 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); } } }; } }); }
在這個方法體裡需要用到部分依賴,需要在pom檔加入如下部分:
<!-- xml --> <dependency> <groupId>org.apache.directory.studio</groupId> <artifactId>org.dom4j.dom4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.8</version> </dependency>
然後將我們的WechatSecurity Controller中的post方法修改為如下,用於做訊息的接收和處理:
@RequestMapping(value = "security", method = RequestMethod.POST) // post方法用于接收微信服务端消息 public void DoPost(HttpServletRequest request,HttpServletResponse response) { System.out.println("这是post方法!"); try{ Map<String, String> map=MessageUtil.parseXml(request); System.out.println("============================="+map.get("Content")); }catch(Exception e){ logger.error(e,e); } }
因為前面我們已經開啟了我們的開發者模式,那麼當我們在這裡將我們程式碼發布之後再公眾號上發送訊息,在們的後台就能看到我們的訊息體進入並解析成功了,這裡我輸出的是微信的【原始ID】,截圖大致如下:
在這裡我只是做了訊息體的接收和轉換成Map,並沒有對訊息做出來,那麼下一篇我們將講述對訊息的分類處理!感謝你的翻閱,如有疑問可以留言討論!
以上是接收微信伺服器post訊息體的java程式碼範例的詳細內容。更多資訊請關注PHP中文網其他相關文章!