在講微信公衆號開發以前,先來大概瞭解一下微信公衆號。微信公衆號大致上能夠分爲服務號和訂閱號,訂閱號和服務號的區別以下:html
訂閱號更加偏向於向用戶傳遞諮詢,通常各類技術類公衆號都屬於訂閱號,訂閱號的消息推送並不會有太顯眼的提醒,若是你想讓某個公衆號的推送內容更加顯眼,能夠選擇置爲星標。置爲星標後公衆號會顯示在全部訂閱號的最頂部,同時收到消息後會有黃色五角星星標提醒。java
微信官方提供了很是完善的接入文檔,若是想了解文檔的具體內容,直接瀏覽器搜索微信開發文檔就能夠了。可是爲了方便開發,通常不會直接去根據微信開發文檔進行開發,gitee上有許多開源項目對微信開發文檔進行了封裝,這裏我使用mica-weixin
開發包進行演示,mica-weixin
是jfinal-weixin
的boot版本。git
配置服務器信息很簡單,具體流程就是微信服務發送請求一個請求給業務服務器,業務服務器驗證請求後給微信服務一個響應。github
本地搭建一個spring-boot-weixin
的項目,使用內網穿透工具進行穿透,使其能夠與外網進行通訊。redis
mica-weixin
依賴<dependency> <groupId>net.dreamlu</groupId> <artifactId>mica-weixin</artifactId> <version>2.0.1</version> </dependency>
mica-weixin
經過配置文件進行公衆號信息的配置,若是你想經過數據庫配置公衆號信息,能夠參考我之前寫過的一篇文章jfinal-weixin自定義配置支持多公衆號。spring
dream: weixin: wx-configs: - appId: xxxxxx appSecret: xxxxxx token: javatrip encodingAesKey: xxxxxx
appId
和appSecret
可在公衆號後臺進行查看,具體位置在菜單開發—>基本配置中,其中appSecret
要妥善保管,如今公衆號已經不支持查看appSecret
了,若是你忘了appSecret
,只能進行重置。數據庫
mica-weixin
已經爲咱們提供好了消息校驗接口,只須要繼承DreamMsgControllerAdapter
就能夠了。api
@WxMsgController("/weixin/wx") public class WeiXinMsgController extends DreamMsgControllerAdapter { @Override protected void processInFollowEvent(InFollowEvent inFollowEvent) { } @Override protected void processInTextMsg(InTextMsg inTextMsg) { } @Override protected void processInMenuEvent(InMenuEvent inMenuEvent) { } }
同時,須要開啓緩存,因爲mica-weixin
的將access_token
等信息放在了緩存中。在啓動類上加@EnableCaching
就開啓了。瀏覽器
@SpringBootApplication @EnableCaching public class WeixinApplication { public static void main(String[] args) { SpringApplication.run(WeixinApplication.class, args); } }
使用內網穿透工具穿透內網地址,而後在公衆號後臺菜單開發—>基本配置中填寫服務器配置信息。緩存
填寫完成後點擊啓用,這樣就完成了微信服務器和業務服務器的關係配置。開啓開發者配置後,自動回覆、自定義菜單等功能都不能正常使用了。這時候就須要去調用對應的接口實現這些功能。
在一步中,自定義類WeiXinMsgController
中須要重寫三個父類中的方法,其中processInFollowEvent()
就是關注和取消關注的方法,取消關注後用戶雖然不能收到消息,可是後臺能夠接收到用戶取消關注的事件。
@Override protected void processInFollowEvent(InFollowEvent inFollowEvent) { OutTextMsg defaultMsg = new OutTextMsg(inFollowEvent); // 關注 if(InFollowEvent.EVENT_INFOLLOW_SUBSCRIBE.equals(inFollowEvent.getEvent())){ // 可將關注用戶錄入db,此處能夠獲取到用戶openid String openId = inFollowEvent.getFromUserName(); // 查詢db,根據響應消息類型封裝消息體 if("文本消息"){ OutTextMsg otm = new OutTextMsg(inFollowEvent); otm.setContent("消息內容"); render(otm); return; }else if("圖片消息"){ OutImageMsg oim = new OutImageMsg(inFollowEvent); // 這裏須要調用微信提供的素材接口,將圖片上傳至素材庫。 oim.setMediaId("圖片素材id"); render(oim); return; }else if("圖文消息"){ OutNewsMsg onm = new OutNewsMsg(inFollowEvent); onm.addNews("標題","簡介","圖片地址","圖文連接"); render(onm); return; }else if("視頻消息"){ OutVideoMsg ovm = new OutVideoMsg(inFollowEvent); ovm.setTitle("標題"); ovm.setDescription("簡介"); ovm.setMediaId("視頻素材id"); render(ovm); return; }else{ defaultMsg.setContent("感謝關注"); } } // 取消關注 if(InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE.equals(inFollowEvent.getEvent())){ log.info("用戶取消關注了"); // 此處能夠將取消關注的用戶更新db } }
響應內容跟關注消息同樣,查詢db去匹配關鍵詞,然會根據消息內容封裝對應的消息體進行返回,若是沒匹配到關鍵詞則回覆統一的消息內容。processInTextMsg()
方法就是用來回復關鍵詞消息的。
@Override protected void processInTextMsg(InTextMsg inTextMsg) { String content = inTextMsg.getContent(); // 根據用戶發送的content去查詢db中的響應內容 if("文本消息"){ OutTextMsg otm = new OutTextMsg(inTextMsg); otm.setContent("消息內容"); render(otm); return; }else if("圖片消息"){ OutImageMsg oim = new OutImageMsg(inTextMsg); // 這裏須要調用微信提供的素材接口,將圖片上傳至素材庫。 oim.setMediaId("圖片素材id"); render(oim); return; }else if("圖文消息"){ OutNewsMsg onm = new OutNewsMsg(inTextMsg); onm.addNews("標題","簡介","圖片地址","圖文連接"); render(onm); return; }else if("視頻消息"){ OutVideoMsg ovm = new OutVideoMsg(inTextMsg); ovm.setTitle("標題"); ovm.setDescription("簡介"); ovm.setMediaId("視頻素材id"); render(ovm); return; }else{ OutTextMsg otm = new OutTextMsg(inTextMsg); otm.setContent("暫未查到關鍵詞..."); } }
點擊菜單後也是同樣,經過processInMenuEvent()
方法進行響應內容的回覆。
@Override protected void processInMenuEvent(InMenuEvent inMenuEvent) { String eventKey = inMenuEvent.getEventKey(); // 根據用戶發送的content去查詢db中的響應內容 if("文本消息"){ OutTextMsg otm = new OutTextMsg(inMenuEvent); otm.setContent("消息內容"); render(otm); return; }else if("圖片消息"){ OutImageMsg oim = new OutImageMsg(inMenuEvent); // 這裏須要調用微信提供的素材接口,將圖片上傳至素材庫。 oim.setMediaId("圖片素材id"); render(oim); return; }else if("圖文消息"){ OutNewsMsg onm = new OutNewsMsg(inMenuEvent); onm.addNews("標題","簡介","圖片地址","圖文連接"); render(onm); return; }else if("視頻消息"){ OutVideoMsg ovm = new OutVideoMsg(inMenuEvent); ovm.setTitle("標題"); ovm.setDescription("簡介"); ovm.setMediaId("視頻素材id"); render(ovm); return; }else{ OutTextMsg otm = new OutTextMsg(inMenuEvent); otm.setContent("無效連接,請重試..."); } }
目前,微信提供的接口對訂閱號的限制比較大,未認證的訂閱號基本上只有接收消息的幾個功能接口。
調用接口的時候須要傳遞token
,獲取token須要在微信後臺中配置業務服務器的白名單。以下:
若是須要配置多個白名單ip,使用回車鍵將多個ip分隔開。
mica-weixin
提供了全部的接口封裝,具體可參考它的官方文檔,若是要獲取微信菜單,能夠這樣寫:
@WxApi("weixin/api") public class WeiXinApiController { @GetMapping("menu") @ResponseBody public String getMenu(){ ApiResult menu = MenuApi.getMenu(); return menu.getJson(); } }
@WxApi
這個是它的自定義註解,其實就是包含了@RequestMapping
和@Controller
。
mica-weixin
提供了多公衆號配置的功能,使用ThreadLocal
和appid
進行綁定。只須要簡單配置便可實現多公衆號配置。
dream: weixin: wx-configs: - appId: xxxxxx appSecret: xxxxxx token: javatrip encodingAesKey: xxxxxx - appId: xxxxxx appSecret: xxxxxx token: javatrip encodingAesKey: xxxxxx
access_token
的有效期是2小時,而且該接口有調用次數限制,mica-weixin
將access_token
存儲在redis中,避免每次調用接口都去獲取access-token
,所以項目須要配置redis。
spring: redis: host: localhost port: 6379
若是想要開發微信公衆號的後臺管理功能,多公衆號的時候就須要手動去指定當前線程使用哪一個公衆號信息。以下:
ApiConfigKit.setThreadLocalAppId(appid);
至此,SpringBoot開發微信公衆號就算完成了,因爲訂閱號開放的接口太少了,好多功能不能正常演示。還有mica-weixin
也許不是最好的選擇,若是想試着開發微信公衆號,能夠在gitee上找一下開發包。至於我爲何會使用mica-weixin
,是由於我曾用過一段時間的jfinal
框架,與之配套的微信開發包就是jfinal-weixin
,也就是jfinal版的mica-weixin
。
star
支持一下!spring-boot-route(一)Controller接收參數的幾種方式
spring-boot-route(二)讀取配置文件的幾種方式
spring-boot-route(五)整合Swagger生成接口文檔
spring-boot-route(六)整合JApiDocs生成接口文檔
spring-boot-route(七)整合jdbcTemplate操做數據庫
spring-boot-route(八)整合mybatis操做數據庫
spring-boot-route(九)整合JPA操做數據庫
spring-boot-route(十一)數據庫配置信息加密
spring-boot-route(十二)整合redis作爲緩存
spring-boot-route(十三)整合RabbitMQ
spring-boot-route(十五)整合RocketMQ
spring-boot-route(十六)使用logback生產日誌文件
spring-boot-route(十七)使用aop記錄操做日誌
spring-boot-route(十八)spring-boot-adtuator監控應用
spring-boot-route(十九)spring-boot-admin監控服務
spring-boot-route(二十)Spring Task實現簡單定時任務
spring-boot-route(二十一)quartz實現動態定時任務
spring-boot-route(二十二)實現郵件發送功能
這個系列的文章都是工做中頻繁用到的知識,學完這個系列,應付平常開發綽綽有餘。若是還想了解其餘內容,掃面下方二維碼告訴我,我會進一步完善這個系列的文章!