管理access_token
access_token介紹
在前面我們成功的使用了Spring Boot Web程序和微信對接。但是這僅僅是一個開始耸序,我們還需要獲取access_token忍些,也就是憑據,才能進行之后的工作佑吝。微信開發(fā)文檔有如下介紹坐昙。
access_token是公眾號的全局唯一接口調用憑據,公眾號調用各接口時都需使用access_token芋忿。開發(fā)者需要進行妥善保存炸客。access_token的存儲至少要保留512個字符空間。access_token的有效期目前為2個小時戈钢,需定時刷新痹仙,重復獲取將導致上次獲取的access_token失效。
微信開發(fā)文檔建議我們使用一個中控服務器殉了,獲取和刷新token均由服務器進行开仰,我們的程序只從中控服務器獲取access_token。由于每次獲取access_token都會刷新一個新token,因此如果在程序中直接獲取众弓,可能造成token不一致和過期問題恩溅。
Spring Boot緩存配置
當然實際上并不是一定要另外整一個服務器。我們利用Spring的緩存功能谓娃,也可以比較好的完成任務脚乡。下面就來介紹一下。
首先滨达,現(xiàn)在Spring Boot項目中添加下面的依賴奶稠,啟用Spring的緩存功能。
compile('org.springframework.boot:spring-boot-starter-cache')
上面的依賴僅僅啟用了Spring Boot的緩存抽象和自動配置功能捡遍。我們還需要選擇具體的緩存實現(xiàn)锌订。Spring Boot支持多種Java 緩存實現(xiàn)。我隨便挑了個caffeine画株,它是由Guava庫獨立出來的緩存庫辆飘,使用Java 8編寫,我看著不錯污秆。
compile 'com.github.ben-manes.caffeine:caffeine:2.4.0'
Spring Boot會自動配置caffeine劈猪,所以我們可以完全透明的使用它。當然良拼,還需要進行一點配置战得。由于微信的access_token的過期時間為7200秒,所以我們的緩存需要在這之前獲取新的token庸推。因此這里將caffeine的過期時間配置為7000秒常侦,在application.properties
中設置即可。
spring.cache.caffeine.spec=expireAfterWrite=7000s
緩存是配置好了贬媒,但是這就能直接使用了嗎聋亡?當然不是,我們還需要編寫獲取token的服務际乘。獲取access_token需要微信公眾平臺開發(fā)者頁面上的appid和appsecret坡倔,我們先要獲取到它,然后配置到application.properties
中脖含。
yitian.study.weixin.appid=XXXXXXXXXXXXX
yitian.study.weixin.appsecret=XXXXXXXXXXXXX
獲取憑據
獲取access_token需要向https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
發(fā)送一個GET請求罪塔,并包含appid和appsecret兩個參數(shù)。如果成功獲取到token养葵,微信服務器會返回下面這樣的json征堪。
{"access_token":"ACCESS_TOKEN","expires_in":7200}
如果出現(xiàn)錯誤,則會返回錯誤信息json关拒。
{"errcode":40013,"errmsg":"invalid appid"}
所以Kotlin代碼可以寫成這樣佃蚜。在方法上使用了@Cacheable注解庸娱,Spring會將方法結果緩存起來,下次直接使用緩存結果谐算。
@Service
class AccessTokenService(
@Value("\${yitian.study.weixin.appid}") val appId: String,
@Value("\${yitian.study.weixin.appsecret}") val appSecret: String,
@Autowired val objectMapper: ObjectMapper
) {
@Cacheable("access_token")
fun refreshAccessToken(): String {
val requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appId&secret=$appSecret"
val json = URL(requestUrl).readText()
try {
val result = objectMapper.readValue(json, AccessTokenResult::class.java)
return result.accessToken
} catch (ex: JsonMappingException) {
val error = objectMapper.readValue(json, ErrorResult::class.java)
throw AccessTokenException(ex, error.toString())
}
}
}
在上面的代碼中注入了Spring Boot自動配置的ObjectMapper熟尉,用于將結果json轉換為Kotlin對象。上面用到的Bean和異常定義在下面氯夷。
data class ErrorResult(
@JsonProperty("errcode") val errorCode: Int,
@JsonProperty("errmsg") val errorMessage: String
) {
}
data class AccessTokenResult(
@JsonProperty("access_token") val accessToken: String,
@JsonProperty("expires_in") val expiresIn: Int) {
}
class AccessTokenException(val ex: Throwable, val msg: String) : Throwable(msg, ex) {
}
這樣臣樱,access_token的管理工作就算完成了。以后我們需要獲取access_token腮考,直接從AccessTokenService調用就行了。
自定義菜單
對于個人性質的訂閱號玄捕,沒有自定義菜單等高級功能踩蔚。所以下面我改用微信測試號來驗證這些功能。另外枚粘,我們可以使用微信公眾平臺的在線調試工具來幫助我們開發(fā)馅闽。
從微信開發(fā)文檔的截圖來看,我猜它很久沒更新過了馍迄。怪不得寫的并不咋地福也,我看了半天也沒明白怎么創(chuàng)建自定義菜單。從網上找了一篇微信公眾平臺開發(fā)(八) 自定義菜單功能開發(fā)攀圈,雖然用的是PHP語言,但是講的還可以。
新建菜單
首先先看看微信文檔的注意事項软吐。
1呛梆、自定義菜單最多包括3個一級菜單,每個一級菜單最多包含5個二級菜單犬辰。
2嗦篱、一級菜單最多4個漢字,二級菜單最多7個漢字幌缝,多出來的部分將會以“...”代替灸促。
3、創(chuàng)建自定義菜單后涵卵,菜單的刷新策略是浴栽,在用戶進入公眾號會話頁或公眾號profile頁時,如果發(fā)現(xiàn)上一次拉取菜單的請求在5分鐘以前缘厢,就會拉取一下菜單吃度,如果菜單有更新,就會刷新客戶端的菜單贴硫。測試時可以嘗試取消關注公眾賬號后再次關注椿每,則可以看到創(chuàng)建后的效果伊者。
需要創(chuàng)建菜單的時候,我們需要向微信發(fā)送一個[https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN](https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN)
的POST請求间护,
請求體是類似這樣的JSON亦渗。這些按鈕的type屬性可以指定為多種按鈕類型,有不同的作用汁尺。這些按鈕類型和JSON屬性的詳細信息直接參考官方文檔吧法精。
{
"button": [
{
"name": "實用功能",
"sub_button": [
{
"type": "click",
"name": "天氣預報",
"key": "weather_forecast"
},
{
"type": "click",
"name": "說個笑話",
"key": "speak_jokes"
}
]
},
{
"type": "media_id",
"name": "捐贈作者",
"media_id": "g78zk9TnnoFBaGJV4jpEDqR2y-fDNgOOFQkiCfrZIbA"
}
]
}
如果添加菜單成功,就會返回這樣的JSON字符串痴突。
{"errcode":0,"errmsg":"ok"}
如果出現(xiàn)錯誤搂蜓,就會返回錯誤碼和錯誤信息。
{"errcode":40018,"errmsg":"invalid button name size"}
本來我想著找一個比較好用的Java/Kotlin的HTTP傳輸庫來進行這些接口的操作辽装。但是找了半天居然沒發(fā)現(xiàn)比較好用的帮碰,只有一個比較舊的Apache HttpClient,最近更新時間還是2011年拾积。怪不得我看網上關于Java開發(fā)微信的資源比較少殉挽,原來真的挺麻煩的。
所以呢拓巧,這個功能就這樣作罷吧斯碌。如果需要更新菜單可以使用在線調試工具,這個倒是比較方便肛度。
查詢自定義菜單
這個倒是比較簡單傻唾。我們只要向下面的URL發(fā)送GET請求即可,微信服務器就會將對應的自定義菜單的JSON格式返回給我們贤斜。
https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
刪除自定義菜單
刪除自定義菜單也很簡單策吠,同樣的,向下面的URL發(fā)送GET請求即可瘩绒。
https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
結語
本來微信開發(fā)還有很多內容猴抹。但是到了這里我就完全不想寫了。一來與微信交互需要發(fā)送多種類型的HTTP請求給微信服務器锁荔。但是我找了一下沒找到好用的Java或Kotlin類庫蟀给。二來微信的官方開發(fā)文檔寫的實在是捉急,例子殘缺不全阳堕,很多地方也沒講明白跋理。我強行硬啃Spring英文文檔都能看個八九不離十。但是我看微信的官方中文文檔居然有地方看不懂恬总。所以這系列就到此為止了前普。謝謝大家的支持!
代碼放在csdn代碼庫上了壹堰,雖然不是一個完整的項目拭卿,但是包含了與微信對接和管理憑據的一點代碼骡湖。對于想用Java或Kotlin開發(fā)微信公眾號的同學可能有一點參考價值。