亚洲精品亚洲人成在线观看麻豆,在线欧美视频一区,亚洲国产精品一区二区动图,色综合久久丁香婷婷

              當(dāng)前位置:首頁 > IT技術(shù) > 微信平臺 > 正文

              Spring Boot 如何給微信公眾號返回消息
              2021-07-29 14:50:31

              hello 各位小伙伴,今天我們來繼續(xù)學(xué)習(xí)如何通過 Spring Boot 開發(fā)微信公眾號。還沒閱讀過上篇文章的小伙伴建議先看看上文,有助于理解本文:

              • Spring Boot 開發(fā)微信公眾號后臺

              上篇文章中我們將微信服務(wù)器和我們自己的服務(wù)器對接起來了,并且在自己的服務(wù)器上也能收到微信服務(wù)器發(fā)來的消息,本文我們要看的就是如何給微信服務(wù)器回復(fù)消息。

              消息分類

              在討論如何給微信服務(wù)器回復(fù)消息之前,我們需要先來了解下微信服務(wù)器發(fā)來的消息主要有哪些類型以及我們回復(fù)給微信的消息都有哪些類型。

              在上文中大家了解到,微信發(fā)送來的 xml 消息中有一個 MsgType 字段,這個字段就是用來標(biāo)記消息的類型。這個類型可以標(biāo)記出這條消息是普通消息還是事件消息還是圖文消息等。

              普通消息主要是指:

              • 文本消息
              • 圖片消息
              • 語音消息
              • 視頻消息
              • 小視頻消息
              • 地址位置消息
              • 鏈接消息

              不同的消息類型,對應(yīng)不同的 MsgType,這里我還是以普通消息為例,如下:

              消息類型 MsgType
              文本消息 text
              圖片消息 image
              語音消息 voice
              視頻消息 video
              小視頻消息 shortvideo
              地址位置消息 location
              鏈接消息 link

              大家千萬不要以為不同類型消息的格式是一樣的,其實是不一樣的,也就是說,MsgType 為 text 的消息和 MsgType 為 image 的消息,微信服務(wù)器發(fā)給我們的消息內(nèi)容是不一樣的,這樣帶來一個問題就是我無法使用一個 Bean 去接收不同類型的數(shù)據(jù),因此這里我們一般使用 Map 接收即可。

              這是消息的接收,除了消息的接收之外,還有一個消息的回復(fù),我們回復(fù)的消息也有很多類型,可以回復(fù)普通消息,也可以回復(fù)圖片消息,回復(fù)語音消息等,不同的回復(fù)消息我們可以進行相應(yīng)的封裝。因為不同的返回消息實例也是有一些共同的屬性的,例如消息是誰發(fā)來的,發(fā)給誰,消息類型,消息 id 等,所以我們可以將這些共同的屬性定義成一個父類,然后不同的消息再去繼承這個父類。

              返回消息類型定義

              首先我們來定義一個公共的消息類型:

              public class BaseMessage {
                  private String ToUserName;
                  private String FromUserName;
                  private long CreateTime;
                  private String MsgType;
                  private long MsgId;
                  //省略 getter/setter
              }
              

              在這里:

              • ToUserName 表示開發(fā)者的微信號
              • FromUserName 表示發(fā)送方賬號(用戶的 OpenID)
              • CreateTime 消息的創(chuàng)建時間
              • MsgType 表示消息的類型
              • MsgId 表示消息 id

              這是我們的基本消息類型,就是說,我們返回給用戶的消息,無論是什么類型的消息,都有這幾個基本屬性。然后在此基礎(chǔ)上,我們再去擴展出文本消息、圖片消息 等。

              我們來看下文本消息的定義:

              public class TextMessage extends BaseMessage {
                  private String Content;
                  //省略 getter/setter
              }
              

              文本消息在前面消息的基礎(chǔ)上多了一個 Content 屬性,因此文本消息繼承自 BaseMessage ,再額外添加一個 Content 屬性即可。

              其他的消息類型也是類似的定義,我就不一一列舉了,至于其他消息的格式,大家可以參考微信開放文檔(http://1t.click/aPXK)。

              返回消息生成

              消息類型的 Bean 定義完成之后,接下來就是將實體類生成 XML。

              首先我們定義一個消息工具類,將常見的消息類型枚舉出來:

              /**
               * 返回消息類型:文本
               */
              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 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 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_VIDEO = "video";
              /**
               * 請求消息類型:推送
               */
              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";
              /**
               * 事件類型:VIEW(自定義菜單 URl 視圖)
               */
              public static final String EVENT_TYPE_VIEW = "VIEW";
              /**
               * 事件類型:LOCATION(上報地理位置事件)
               */
              public static final String EVENT_TYPE_LOCATION = "LOCATION";
              /**
               * 事件類型:LOCATION(上報地理位置事件)
               */
              public static final String EVENT_TYPE_SCAN = "SCAN";
              

              大家注意這里消息類型的定義,以 RESP 開頭的表示返回的消息類型,以 REQ 表示微信服務(wù)器發(fā)來的消息類型。然后在這個工具類中再定義兩個方法,用來將返回的對象轉(zhuǎn)換成 XML:

              public static String textMessageToXml(TextMessage textMessage) {
                  xstream.alias("xml", textMessage.getClass());
                  return xstream.toXML(textMessage);
              }
              private static XStream xstream = new XStream(new XppDriver() {
                  public HierarchicalStreamWriter createWriter(Writer out) {
                      return new PrettyPrintWriter(out) {
                          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);
                              }
                          }
                      };
                  }
              });
              

              textMessageToXML 方法用來將 TextMessage 對象轉(zhuǎn)成 XML 返回給微信服務(wù)器,類似的方法我們還需要定義 imageMessageToXml、voiceMessageToXml 等,不過定義的方式都基本類似,我就不一一列出來了。

              返回消息分發(fā)

              由于用戶發(fā)來的消息可能存在多種情況,我們需要分類進行處理,這個就涉及到返回消息的分發(fā)問題。因此我在這里再定義一個返回消息分發(fā)的工具類,如下:

              public class MessageDispatcher {
                  public static String processMessage(Map<String, String> map) {
                      String openid = map.get("FromUserName"); //用戶 openid
                      String mpid = map.get("ToUserName");   //公眾號原始 ID
                      if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) { 
                          //普通文本消息
                          TextMessage txtmsg = new TextMessage();
                          txtmsg.setToUserName(openid);
                          txtmsg.setFromUserName(mpid);
                          txtmsg.setCreateTime(new Date().getTime());
                          txtmsg.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
                          txtmsg.setContent("這是返回消息");
                          return MessageUtil.textMessageToXml(txtmsg);
                      }
                      return null;
                  }
                  public String processEvent(Map<String, String> map) {
                      //在這里處理事件
                  }
              }
              

              這里我們還可以多加幾個 elseif 去判斷不同的消息類型,我這里因為只有普通文本消息,所以一個 if 就夠用了。

              在這里返回值我寫死了,實際上這里需要根據(jù)微信服務(wù)端傳來的 Content 去數(shù)據(jù)中查詢,將查詢結(jié)果返回,數(shù)據(jù)庫查詢這一套相信大家都能搞定,我這里就不重復(fù)介紹了。

              最后在消息接收 Controller 中調(diào)用該方法,如下:

              @PostMapping(value = "/verify_wx_token",produces = "application/xml;charset=utf-8")
              public String handler(HttpServletRequest request, HttpServletResponse response) throws Exception {
                  request.setCharacterEncoding("UTF-8");
                  Map<String, String> map = MessageUtil.parseXml(request);
                  String msgType = map.get("MsgType");
                  if (MessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(msgType)) {
                      return messageDispatcher.processEvent(map);
                  }else{
                      return messageDispatcher.processMessage(map);
                  }
              }
              

              在 Controller 中,我們首先判斷消息是否是事件,如果是事件,進入到事件處理通道,如果不是事件,則進入到消息處理通道。

              注意,這里需要配置一下返回消息的編碼,否則可能會出現(xiàn)中文亂碼。

              如此之后,我們的服務(wù)器就可以給公眾號返回消息了。

              上篇文章發(fā)出后,有小伙伴問松哥這個會不會開源,我可以負(fù)責(zé)任的告訴大家,肯定會開源,這個系列截稿后,我把代碼處理下就上傳到 GitHub。

              好了,本文我們就先說到這里。

              ?
              Spring Boot 如何給微信公眾號返回消息_Java

              ?

              本文摘自 :https://blog.51cto.com/u

              開通會員,享受整站包年服務(wù)立即開通 >