微信公眾號快速開發(二)專案搭建與被動回覆

永動的圖靈機發表於2019-07-14

工具:idea2018,jdk1.8,框架:springboot+thymeleaf

基礎搭建

說明,本專案著力於快速開發,前端頁面只做最基本的頁面跳轉和引數校驗。若是需要前後端分離,可參考一些開源的專案,如givebest/node.js-wechat-js-sdk

準備

一、測試/正式賬號公眾平臺測試賬號,根據上一篇註冊即可

二、web開發者工具,拖至文末,選擇適配版本下載即可。(因為微信部分URL需要許可權的校驗,只能在微信瀏覽器內開啟,而類似postman的第三方工具無法使用)

三、公網可訪問地址,如阿里雲,或內網穿透工具,可參考上一篇中【介面配置資訊修改】。(我的是http://chety.mynatapp.cc -> 127.0.0.1:8080,已開啟狀態)

四、訂閱測試號,掃描二維碼即可

微信公眾號快速開發(二)專案搭建與被動回覆

開始開發——被動回覆

描述

向公眾號傳送訊息,公眾號原樣返回我們的內容,如傳送【你好】,公眾號回覆【你好】

實現思路

一、參考微信公眾平臺技術文件,選擇【訊息管理】模組中的【接收普通訊息】。

微信公眾號快速開發(二)專案搭建與被動回覆

二、根據接收普通訊息的介紹,可知:

  • 訊息型別分為:文字訊息,圖片訊息,語音訊息,視訊訊息等
  • 訊息的資料包請求格式為xml,請求方式為post
  • 訊息請求有重試和加密機制
  • 接收訊息的URL與接入驗證的路徑一致,用請求方式來區分

三、引數介紹

如文字訊息,有訊息的傳送的接收方,訊息型別和內容等。可使用bean物件來封裝該訊息格式

  • ToUserName:開發者微訊號,即目前我正在使用的測試公眾號
  • FromUserName:傳送方賬號,描述為一個openid,即一個手機微信使用者在一公眾號下的唯一標識,無論何種客戶端裝置訪問,該id都是統一且唯一的。

注意:訊息的收發方是相對的,客戶端與服務端相反

微信公眾號快速開發(二)專案搭建與被動回覆

程式碼開發

一、新建springboot專案,需要的核心依賴如下:

<dependencies>
    <!-- web專案 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.0.1</version>
    </dependency>
    <!-- 引入thymeleaf -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- alibaba druid連線池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>
    <!-- lombok JavaBean工具 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.8</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
        <version>4.4.11</version>
    </dependency>
    <!-- http客戶端工具 -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.9</version>
    </dependency>
    <!-- json轉換工具 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.58</version>
    </dependency>
    <!-- 資料庫可選,如專案需要本地儲存支付交易流水 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.26</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>
複製程式碼

二、我這裡都使用預設配置,因此暫時不配置application.yml,各位根據自己的需要配置

傳送訊息

三、根據輸入訊息的欄位,封裝為bean物件

注意,xml中引數的鍵都是大寫,因此定義java引數時,需要使用註解或直接大寫命名

@Data // lombok,包含setter,getter,tostring
@XmlRootElement(name = "xml") // 根節點
@XmlAccessorType(XmlAccessType.FIELD) // 對映類中的所有欄位到XML
public class MsgSendEntity {
    /**
     * 公有部分
     */
    //  開發者微訊號
    @XmlElement(name = "ToUserName") // 指定名稱對映
    private String toUserName;

    // 傳送方帳號(一個OpenID)
    @XmlElement(name = "FromUserName")
    private String fromUserName;

    // 訊息建立時間 (整型)
    @XmlElement(name = "CreateTime")
    private Long createTime;

    // 訊息型別
    @XmlElement(name = "MsgType")
    private String msgType;

    // 訊息id,64位整型
    @XmlElement(name = "MsgId")
    private Long msgId;
    
    // 文字訊息內容
    @XmlElement(name = "Content")
    private String content;
}
複製程式碼

四、URL接入校驗介面,需公網可見或開啟內網穿透工具。詳細內容參考上一篇文章

@Controller
@RequestMapping("/api/v1/wechat1")
public class WeChatController {

    /**
     * url接入校驗
     * @param signature 微信加密簽名,signature結合了開發者填寫的token引數和請求中的timestamp引數、nonce引數。
     * @param timestamp 時間戳
     * @param nonce 隨機數
     * @param echostr 隨機字串
     * @return 若校驗成功,原樣返回echostr引數內容
     */
    @GetMapping("/gzh")
    @ResponseBody
    public String validate(String signature,String timestamp,String nonce,String echostr){
        if (!WeChatUtil.checkSignature(signature, timestamp, nonce)) {
            WeChatUtil.getLogger().info("WeChatController.validate -- 公眾號接入失敗");
            return null;
        }
        WeChatUtil.getLogger().info("WeChatController.validate -- 公眾號接入成功,echostr:{}"+echostr);
        return echostr;
    }
}    
複製程式碼

測試號管理配置如圖:

微信公眾號快速開發(二)專案搭建與被動回覆

五、接收訊息介面(路徑與接入驗證URL的一致)

/**
 * 公眾號訊息處理
 * @param inMsg 客戶端輸入的訊息資訊
 * @return 服務端返回資訊
 */
@PostMapping("gzh")
@ResponseBody
public Object handleMessage(@RequestBody InMsgEntity inMsg) {
    return null;
}    
複製程式碼

六、斷點除錯

微信在測試公眾號(已訂閱)傳送文字訊息

微信公眾號快速開發(二)專案搭建與被動回覆

檢視斷點資訊,可以看到接收到文字訊息的欄位資訊

微信公眾號快速開發(二)專案搭建與被動回覆

放行斷點,可以看到接收訊息時的重試機制

接收訊息

參考技術文件,這裡選擇【被動回覆訊息】

微信公眾號快速開發(二)專案搭建與被動回覆

七、封裝【回覆文字訊息】的實體類

@Data
@XmlRootElement(name="xml")
@XmlAccessorType(XmlAccessType.FIELD)
public class MsgReplyEntity {
    //  使用者的OpenID
    private String ToUserName;
    
    // 測試號的微訊號
    private String FromUserName;
    
    // 訊息建立時間 (整型)
    private Long CreateTime;
    
    // 訊息型別
    private String MsgType;

    // 文字訊息內容
    private String Content;
}
複製程式碼

八、完善訊息處理介面的方法

@PostMapping("gzh")
@ResponseBody
public Object handleMessage(@RequestBody MsgSendEntity msgSend) {
    // 服務端訊息回覆的實體類
    MsgReplyEntity msgReply = new MsgReplyEntity();
    // 根據接收的資訊回覆,接收和傳送方相反
    msgReply.setFromUserName(msgSend.getToUserName());
    msgReply.setToUserName(msgSend.getFromUserName());
    msgReply.setCreateTime(new Date().getTime());    
    msgReply.setMsgType(msgSend.getMsgType());
    // 訊息內容原樣返回
    msgReply.setContent(msgSend.getContent());
    return msgReply;
}    
複製程式碼

測試樣例

一、客戶端傳送訊息測試

微信公眾號快速開發(二)專案搭建與被動回覆


ok,公眾號的簡單被動文字訊息回覆就完成了。當然,其他的訊息型別也類似處理,只需簡單的判斷即可。

相關文章