WxJava微信公眾號開發(fā)入門實戰(zhàn)
WxJava介紹
WxJava是一款基于Java語言的微信開發(fā)Java SDK,它提供了微信支付,開放平臺,小程序,企業(yè)微信,公眾號等多個平臺的API接口,并將其封裝為易于調(diào)用的Java方法,方便Java開發(fā)者快速開發(fā)與微信相關的應用。
GitHub地址:https://github.com/Wechat-Group/WxJava
使用WxJava只需要引入開發(fā)相關模塊的maven依賴即可
<dependency> <groupId>com.github.binarywang</groupId> <artifactId>(不同模塊參考下文)</artifactId> <version>4.5.0</version> </dependency>
微信小程序:weixin-java-miniapp
微信支付:weixin-java-pay
微信開放平臺:weixin-java-open
公眾號(包括訂閱號和服務號):weixin-java-mp
企業(yè)號/企業(yè)微信:weixin-java-cp
微信公眾號
如果沒有個人微信號或者企業(yè)微信號,可以申請測試公眾號,并且擁有所有接口權(quán)限,推薦。
申請測試公眾號
訪問申請測試公眾號,申請一個測試的微信公眾號,測試微信公眾號擁有所有高級功能。
測試公眾號配置
申請測試公眾號后,會分配一個測試的appid和秘鑰,接著配置一個可用于內(nèi)網(wǎng)穿透的地址
注意:URL地址指向本地開發(fā)能訪問的某個接口
掃描測試號二維碼
以關注測試公眾號,同時獲取用戶openid
WxJava微信公眾號開發(fā)
WxJava對應的微信公眾號開發(fā)文檔
添加依賴
非Spring Boot:
<dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-mp</artifactId> <version>4.5.0</version> </dependency>
Spring Boot:
<dependency> <groupId>com.github.binarywang</groupId> <artifactId>wx-java-mp-spring-boot-starter</artifactId> <version>4.5.0</version> </dependency>
配置微信參數(shù)
非Spring Boot方式引入依賴,需要自定義微信相關配置信息,同時需要初始化一個WxMpService實例。
# 自定義微信相關配置信息 wx: # 消息模板ID templateId: o9YG7vWS8It-mddU2Wnknf1jgzTqZtLeBQRLhF54SXQ mp: # 微信公眾號的appid appId: wxba7358c0c621200d # 信公眾號的app secret secret: a0e9521e29a07e298ccba5b2c239958d # 微信公眾號的toke token: token # 微信公眾號的EncodingAESKey aesKey:
Spring Boot方式引入依賴,需要按約定進行微信相關配置,然后就可以直接進行相關開發(fā)。
具體配置參考:wx-java-mp-spring-boot-starter配置
# 公眾號配置(必填) wx.mp.appId = appId wx.mp.secret = @secret wx.mp.token = @token wx.mp.aesKey = @aesKey # 存儲配置redis(可選) wx.mp.config-storage.type = Jedis # 配置類型: Memory(默認), Jedis, RedisTemplate wx.mp.config-storage.key-prefix = wx # 相關redis前綴配置: wx(默認) wx.mp.config-storage.redis.host = 127.0.0.1 wx.mp.config-storage.redis.port = 6379 #單機和sentinel同時存在時,優(yōu)先使用sentinel配置 #wx.mp.config-storage.redis.sentinel-ips=127.0.0.1:16379,127.0.0.1:26379 #wx.mp.config-storage.redis.sentinel-name=mymaster # http客戶端配置 wx.mp.config-storage.http-client-type=httpclient # http客戶端類型: HttpClient(默認), OkHttp, JoddHttp wx.mp.config-storage.http-proxy-host= wx.mp.config-storage.http-proxy-port= wx.mp.config-storage.http-proxy-username= wx.mp.config-storage.http-proxy-password= # 公眾號地址host配置 #wx.mp.hosts.api-host=http://proxy.com/ #wx.mp.hosts.open-host=http://proxy.com/ #wx.mp.hosts.mp-host=http://proxy.com/
wx-java-mp-spring-boot-starter主要自動配置了如下兩個對象:
WxMpService:可以完成微信公眾號提供的各種功能 WxMpConfigStorage:保存了微信公眾號配置信息
實例化WxMpService
非Spring Boot方式引入依賴則需要自己實例化WxMpService對象。
1.創(chuàng)建WxMpProperties類,封裝微信配置參數(shù)信息。
@Component @Data @ConfigurationProperties(prefix = "wx.mp") public class WxMpProperties { /** * 設置微信公眾號的appid */ private String appId; /** * 設置微信公眾號的app secret */ private String secret; /** * 設置微信公眾號的token */ private String token; /** * 設置微信公眾號的EncodingAESKey */ private String aesKey; }
2.創(chuàng)建WxMpConfiguration類,用于配置WxJava相關的實例對象。
@Configuration public class WxMpConfiguration { @Autowired private WxMpProperties wxMpProperties; /** * 微信客戶端配置存儲 */ @Bean public WxMpConfigStorage wxMpConfigStorage() { WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl(); // 設置微信公眾號appId configStorage.setAppId(wxMpProperties.getAppId()); // 設置微信公眾號appSecret configStorage.setSecret(wxMpProperties.getSecret()); // 設置微信公眾號的token configStorage.setToken(wxMpProperties.getToken()); // 設置微信公眾號的EncodingAESKey configStorage.setAesKey(wxMpProperties.getAesKey()); return configStorage; } /** * WxMpService多個實現(xiàn)類 聲明一個實例 */ @Bean public WxMpService wxMpService() { WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); return wxMpService; } }
對接微信公眾號回調(diào)
注意:編寫業(yè)務處理的接口對應測試公眾號中配置的接口地址。
@Slf4j @RestController public class TestController { @Autowired private WxMpService wxMpService; /** * 驗證消息的確來自微信服務器 * <p> * 開發(fā)者通過檢驗signature對請求進行校驗。若確認此次GET請求來自微信服務器,請原樣返回echostr參數(shù)內(nèi)容,則接入生效 * * @param signature 微信加密簽名,signature結(jié)合了開發(fā)者填寫的token參數(shù)和請求中的timestamp參數(shù)、nonce參數(shù)。 * @param timestamp 時間戳 * @param nonce 隨機數(shù) * @param echostr 隨機字符串 * @return */ @GetMapping("send") public String configAccess(String signature, String timestamp, String nonce, String echostr) { // 校驗簽名 if (!wxMpService.checkSignature(timestamp, nonce, signature)) { log.error("簽名校驗 ===》 非法請求"); // 消息簽名不正確,說明不是公眾平臺發(fā)過來的消息 return null; } log.error("簽名校驗 ===》 驗證成功"); // 返回echostr return echostr; } }
接收與回復消息
WxMpXmlOutTextMessage是同步回復給微信消息的對象,不同類型的消息類型可以用不同的方式構(gòu)造
@RequestMapping("send") public String send(@RequestBody String requestBody, @RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce) { // 校驗簽名 if (!wxMpService.checkSignature(timestamp, nonce, signature)) { log.error("簽名校驗 ===》 非法請求"); // 消息簽名不正確,說明不是公眾平臺發(fā)過來的消息 return null; } log.error("簽名校驗 ===》 驗證成功"); // 解析消息體,封裝為對象 WxMpXmlMessage xmlMessage = WxMpXmlMessage.fromXml(requestBody); // 接收消息內(nèi)容 String inContent = xmlMessage.getContent(); // 響應的消息內(nèi)容 String outContent; // 根據(jù)不同的關鍵字回復消息 if (inContent.contains("hello")) { outContent = "hello world"; } else if (inContent.contains("java")) { outContent = "hello java"; } else { outContent = "服務繁忙,暫時不能回復"; } // 構(gòu)造響應消息對象 WxMpXmlOutTextMessage outTextMessage = WxMpXmlOutMessage.TEXT().content(outContent).fromUser(xmlMessage.getToUser()) .toUser(xmlMessage.getFromUser()).build(); // 將響應消息轉(zhuǎn)換為xml格式返回 return outTextMessage.toXml(); }
微信消息路由器
微信推送給公眾號的消息類型很多,而公眾號也需要針對用戶不同的輸入做出不同的反應。避免出現(xiàn)很多if/else判斷,可以使用WxMpMessageRouter來對消息進行路由
WxMpMessageRouter支持從4個角度對消息進行匹配:
msgType event eventKey content
具體參考:微信消息路由器
WxMpMessageHandler
針對不同類型的消息處理,需要自己實現(xiàn)消息處理器,消息處理器必須實現(xiàn)WxMpMessageHandler接口
public interface WxMpMessageHandler { /** * * @param wxMessage * @param context 上下文,如果同一個路由規(guī)則內(nèi)的handler或interceptor之間有信息要傳遞,可以用這個 * @param wxMpService * @return xml格式的消息,如果在異步規(guī)則里處理的話,可以返回null */ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager); }
WxMessageInterceptor
還可以添加攔截器,支持在處理微信公眾號消息時添加攔截器以進行消息的預處理、過濾等操作。自定義實現(xiàn)攔截處理器,實現(xiàn)WxMessageHandler接口
public interface WxMpMessageInterceptor { /** * 攔截微信消息 * @param wxMessage * @param context 上下文,如果handler或interceptor之間有信息要傳遞,可以用這個 * @param wxMpService * @return true代表OK,false代表不OK */ public boolean intercept(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager); }
自定義Handle
@Component public class MyTextHandler implements WxMpMessageHandler { @Override public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { // 接收消息內(nèi)容 String inContent = wxMessage.getContent(); // 響應的消息內(nèi)容 String outContent; // 根據(jù)不同的關鍵字回復消息 if (inContent.contains("hello")) { outContent = "hello world"; } else if (inContent.contains("java")) { outContent = "hello java"; } else if (inContent.contains("***")) { outContent = "請文明用語"; } else { outContent = "服務繁忙,暫時不能回復"; } // 構(gòu)造響應消息對象 return WxMpXmlOutMessage.TEXT().content(outContent).fromUser(wxMessage.getToUser()) .toUser(wxMessage.getFromUser()).build(); } }
自定義Interceptor
/** * 對微信公眾號消息進行預處理、過濾等操作,根據(jù)具體業(yè)務需求決定是否允許繼續(xù)執(zhí)行后面的路由處理方法 * <p> * 如果要中止消息的繼續(xù)處理,即表示攔截了這個消息,需要返回 false。否則,在執(zhí)行完當前攔截器操作后,允許消息的繼續(xù)處理,返回 true */ @Component public class MyTextInterceptor implements WxMpMessageInterceptor { @Override public boolean intercept(WxMpXmlMessage wxMpXmlMessage, Map<String, Object> map, WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException { String msg = wxMpXmlMessage.getContent(); String msgType = wxMpXmlMessage.getMsgType(); if (msgType.equals("text") && msg.contains("混蛋")) { wxMpXmlMessage.setContent("***"); return true; } return true; } }
創(chuàng)建消息路由配置
將不同類型的消息交給不同的消息處理器來處理。路由對象為WxMpMessageRouter
@Configuration public class MessageRouterConfig { @Autowired private WxMpService wxMpService; @Autowired private MyTextHandler textHandler; @Autowired private MyTextInterceptor textInterceptor; @Bean public WxMpMessageRouter messageRouter() { // 創(chuàng)建消息路由 final WxMpMessageRouter router = new WxMpMessageRouter(wxMpService); // 添加一個同步處理文本消息的路由規(guī)則 同時添加interceptor、handler router.rule().async(false).msgType(WxConsts.XmlMsgType.TEXT).interceptor(textInterceptor).handler(textHandler).end(); return router; } }
使用消息路由
在Controller中注入WxMpMessageRouter
,將消息路由到對應的處理器
@Slf4j @RestController public class TestController { @Autowired private WxMpService wxMpService; @Autowired private WxMpMessageRouter wxMpMessageRouter; @RequestMapping("send") public String configAccess(@RequestBody String requestBody, @RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce) { // 校驗簽名 if (!wxMpService.checkSignature(timestamp, nonce, signature)) { log.error("簽名校驗 ===》 非法請求"); // 消息簽名不正確,說明不是公眾平臺發(fā)過來的消息 return null; } log.error("簽名校驗 ===》 驗證成功"); // 解析消息體,封裝為對象 WxMpXmlMessage xmlMessage = WxMpXmlMessage.fromXml(requestBody); WxMpXmlOutMessage outMessage = null; try { // 將消息路由給對應的處理器,獲取響應 outMessage = wxMpMessageRouter.route(xmlMessage); } catch (Exception e) { log.error("消息路由異常", e); } // 將響應消息轉(zhuǎn)換為xml格式返回 return outMessage == null ? null : outMessage.toXml(); } }
執(zhí)行測試
access_token持久化
WxMpConfigStorage是維護微信公眾號相關信息的地方,里面包含
appid、appsecret、token、aes encoding key、access token
等信息。
在與微信API交互過程中,首先需要獲取
access_token
,但是獲取access_token
的微信接口有調(diào)用次數(shù)限制,并且每次交互中都需要去獲取access_token
,需要重新發(fā)起網(wǎng)絡請求,效率低,沒過期就調(diào)用可能會因為達到次數(shù)上限而獲取失敗。
如果是分布式的環(huán)境下,每個服務都要各自去獲取這些信息,因此,可以將這些信息存儲到數(shù)據(jù)庫或分布式緩存中,以便各個節(jié)點能夠共享數(shù)據(jù)信息,尤其是
access token
。
通常是將access_token
持久化到redis,只需要額外在配置文件中增加redis配置即可。
wx: # 消息模板ID templateId: o9YG7vWS8It-mddU2Wnknf1jgzTqZtLeBQRLhF54SXQ mp: # 微信公眾號的appid appId: wxba7358c0c621200d # 信公眾號的app secret secret: a0e9521e29a07e298ccba5b2c239958d # 微信公眾號的toke token: token # 微信公眾號的EncodingAESKey aesKey: config-storage: # 配置類型: Memory(默認), Jedis, Redisson, RedisTemplate type: RedisTemplate # redis前綴配置: wx(默認) key-prefix: wx redis: host: 127.0.0.1 port: 6379
注意:當type使用redisTemplate,則需要單獨引入spring-boot-starter-data-redis
依賴
接下來,在與微信公眾號交互過程中,就會先需要獲取access_token,然后將其存入redis
到此這篇關于WxJava微信公眾號開發(fā)入門實戰(zhàn)的文章就介紹到這了,更多相關WxJava 入門內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
maven項目test執(zhí)行main找不到資源文件的問題及解決
這篇文章主要介紹了maven項目test執(zhí)行main找不到資源文件的問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03Spring中ClassPathXmlApplicationContext類的使用詳解
這篇文章主要介紹了Spring中ClassPathXmlApplicationContext類的使用詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01IntelliJ IDEA 2021.1 EAP 4 發(fā)布:字體粗細可調(diào)整Git commit template 支持
這篇文章主要介紹了IntelliJ IDEA 2021.1 EAP 4 發(fā)布:字體粗細可調(diào)整,Git commit template 支持,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02Mockito mock Kotlin Object類方法報錯解決方法
這篇文章主要介紹了Mockito mock Kotlin Object類方法報錯解決方法,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-09-09