.picUrl("http://k2.jsqq.net/uploads/allimg/1702/7_170225142233_1.png")
.url("http://baidu.com").build())
.build();
}
/**
* 接受用戶文本消息,異步返回文本消息
* @param content
* @return dummy
*/
@WxMessageMapping(type = WxMessage.Type.TEXT, wildcard = "2*")
@WxAsyncMessage
public String text2(WxRequestBody.Text text, String content) {
boolean match = text.getContent().equals(content);
return "收到消息內容為" + content + "!結果匹配!" + match;
}
}
4. 配置內網穿透
因為微信公眾號需要配置自己的服務器接口,測試時可直接使用本地進行測試,使用內網穿透可以令微信公眾平臺訪問到你自己本地的服務器。
軟件可使用ngrok或者natapp,使用方式請參考兩者官方文檔。
在測試公眾號的接口配置信息中填寫在第三步中生成的域名,token使用配置文件中的token,保存後,如果不出意外應該會驗證成功。如有問題請及時反饋。
二、示例說明
上面的示例在啟動後,請關注自己的公眾號,此時公眾號的菜單應該是有兩個主菜單:左、右,同時左有兩個子菜單:文本消息、點擊鏈接。
在點擊文本消息菜單時,會收到文本消息,內容為:測試文本消息。
在點擊第二個點擊鏈接時,會跳轉至百度,並收到一條圖文消息,標題是測試圖文消息。
給公眾號發送文本消息,消息內容不是1開頭時,會收到公眾號回覆內容:”收到消息內容為” + 發送的內容。
給公眾號發送文本消息,消息內容是1開頭時,會收到圖文消息的回覆。
當有用戶退訂公眾號時,會在System.out中打印用戶暱稱 + “退訂了公眾號”
三、示例講解
註解@WxApplication用於聲明該應用為微信application,並使用SpringApplication啟動。若已有SpringBoot環境,請在你的@SpringApplication類上加入註解@EnableWxMvc,效果一樣。可以看源碼。
註解@WxController用於聲明該類為微信Controller,只有聲明瞭這個註解,才會綁定在微信服務器的請求映射中,否則該類會被忽略。
註解@WxButton(group = WxButton.Group.LEFT, main = true, name = “左”)用於聲明一個按鈕箱,group代表分組,有左中右三個分組,分別對應微信的三個一級菜單。main為boolean值,代表該菜單項是否為一級菜單。name就是菜單名。
註解@WxButton(type = WxButton.Type.CLICK, group = WxButton.Group.LEFT, order = WxButton.Order.FIRST, name = “文本消息”) 用於聲明左邊分組的子菜單,order代表順序,這裡是第一個。
public String leftFirst(WxRequest wxRequest, WxUser wxUser) { return “測試文本消息”; } 這裡有三個點:
- WxRequest是自動綁定的參數,當用戶在公眾號上進行某些操作後,微信服務器會給配置中填寫的域名的根路徑發送一個Post請求,請求內容是xml格式的消息,這條消息內容中標記了具體的信息,可參考公眾號文檔。這裡wxRequest為封裝過的微信請求內容,可以通過這個wxRequest獲得一些信息。
- wxUser是通過微信api接口獲取的用戶相關信息,這個還涉及到另外一個內容,後面講解。
- 返回String,此時會直接使用微信定義的文本消息,同步返回給用戶,即直接對微信服務器的這個請求進行響應,參考:被動回覆消息。
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543
@WxButton(type = WxButton.Type.VIEW, group = WxButton.Group.LEFT, order = WxButton.Order.SECOND, url = “http://baidu.com“, name = “點擊鏈接”) 該註解同上面,類型變為View,具體內容可參考該枚舉註釋,或者公眾號文檔。注意每種菜單類型都有自己的限制,請參考文檔,如不滿足條件啟動時就會發生異常。
註解@WxAsyncMessage表明異步回覆消息,參考客服消息,暫時未對多客服進行支持。
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547
WxMessage.News.builder(),在WxMessage類中,有不同的靜態內部類,以及他們的builder,通過builder可以方便的構造微信不同類型的消息,請參考被動回覆消息和客服消息。
註解@WxEventMapping(type = WxEvent.Type.UNSUBSCRIBE)綁定取消訂閱事件,當有用戶取消關注時,會進入這個註解下面的邏輯。還有一點要註解,WxEventMapping所有的回覆內容都會被異步發送給用戶。
註解@WxMessageMapping(type = WxMessage.Type.TEXT)表示綁定用戶發送的文本消息到下面的方法邏輯,public String text(String content) { return “收到消息內容為” + content; }。content會自動被賦值為用戶發送的文本內容。
註解@WxMessageMapping(type = WxMessage.Type.TEXT, wildcard = “1*”)與上面相同,不同的是wildcard通配符,該通配符支持對消息內容做通配,覆蓋該通配邏輯的會進入下面的執行邏輯。
四、功能支持
1. Spring Boot風格的啟動方式
與Spring Boot完美整合,如果自己沒有SpringBoot項目,想直接使用該框架搭建公眾號,可直接使用@WxApplication標記啟動類,該註解支持參數:menuAutoCreate,默認為true。表示自動創建微信菜單,可以設置為false關閉自動創建菜單的行為。若已有Spring Boot項目,想引入此框架,只需在你的任意配置類上標記註解@EnableWxMvc即可,參數同上。
2. Spring Mvc風格的Mapping
共支持三種Mapping:
- @WxButton,微信按鈕綁定與生成。參數說明:group表示左中右三個分組,name為按鈕名,type菜單類型,main是否為一級菜單。order顯示順序。key為事件key,若交給框架管理,則key會自動生成,無需配置。url為view類型的訪問地址。mediaId為媒體ID。
- @WxMessageMapping,微信消息綁定。參數說明:type消息類型、wildcard通配符支持多個、pattern正則表達式,暫時不支持哈哈、name綁定名,不必要。
- @WxEventMapping,微信事件綁定。參數說明:type事件類型、name綁定名,不必要。
注意:綁定所在類需聲明為@WxController
3. Spring Mvc風格的參數綁定
支持以下類型參數:
- WxRequest:微信服務器的請求封裝
- WxRequest.Body:微信服務器的請求體內容封裝
- WxRequest.Body.field:WxRequest裡的任意屬性名,都可以直接綁定到參數,但是要注意消息類型與參數值,有些消息不會有某些內容。暫時還不支持不同消息區分綁定的不同的Request類型,後續可加入支持。
- WxSession:類比於HttpSession,默認實現使用fromUserName作為sessionId
- WxUser:這個是較為特殊的類型,其實是通過WxUserProvider接口提供的,本框架提供一個默認的實現DefaultWxUserProvider implements WxUserProvider
,該實現通過微信api獲取用戶信息,以WxUser類型返回,當然你也可以使用自己的實現類,只用聲明為SpringBean即可自動注入,泛型類型也可以由你自己確定,參數中有該泛型類型的參數,都會被自動使用WxUserProvider.getUser獲取並綁定到參數中。
參數綁定目前支持這幾種,如果有更好的方案需要支持,也可以直接提出意見與建議,我會及時進行處理的。
4. Spring Mvc風格的返回值
返回值支持以下類型:
- String 該返回值會以文本消息形式返回給用戶
- WxMessage及其子類 該返回值可以很方便的使用對應消息類型的Builder去構造,此時會以對應類型的消息返回給用戶。
- @WxAsyncMessage 標記異步返回消息,通過這個註解,可以令消息的返回值以異步消息的形式調用客服接口發送給用戶。@WxEventMapping的返回值只能以這種形式發送。
- String或者WxMessage的Iterable或者Array。該類型會分為多條異步消息發送給用戶。
上面異步發送消息都是使用的WxMessageTemplate發送的,下面講解。
5. Spring風格的消息發送
本框架提供WxMessageTemplate發送消息,同時在template中提供了WxMessageProcesser支持,作用是在消息發送前對消息做處理。
如同步返回消息時,需要寫入fromUserName字段,而該字段是消息發送時的toUserName字段,沒有必要讓框架的使用者去處理這個字段,在WxCommonMessageProcesser處理器中就對該字段進行了處理,有興趣的可以參考源碼。
同時還支持以下轉換:對於media類型的消息,可以直接使用mediaUrl或者mediaPath寫入素材路徑,消息轉換器通過WxMediaManager自動管理素材獲得必要的素材id。(關於WxMediaManager下面寫)
注意:所有的消息處理文本消息,建議都使用WxMessage裡的對應消息內容的builder來生成!
6. 素材自動管理
本框架提供WxMediaManager來管理素材,同時使用嵌入式數據庫保存素材與本地文件的對應關係,目前這部分功能我雖然完成了,但是總感覺有很大的不妥,希望有人能幫我看看順便提點意見。
上面消息發送中的媒體其實也是通過素材管理器來實現的。
7. 內置AccessToken管理
本框架提供WxTokenStore接口來存儲token,並提供一個默認的基於內存的實現MemoryWxTokenStore,若有分佈式需要可以自行實現該接口,並把實現類作為Bean注入Spring即可。
使用WxApiInvokeSpi接口與WxInvokerProxyFactory工廠類自動生成微信接口調用代理,只需要聲明方法和註解即可,默認使用HttpComponent調用接口。有興趣的小夥伴可以看看源碼,我寫的也不太好,有更好的建議歡迎提出。
同時對返回值做初步分析,如果接口返回內容的errorCode不為0,則會作為異常拋出。異常體系為WxException及其子類。
PS:你也可以使用這種方式任意生成自己的代理調用接口,後續我會加入文檔,暫時懶。。。
9. 菜單自動生成與自動更新
可以通過開關開啟與關閉,通過@WxButton註解生成菜單結構,並自動調用接口判斷菜單是否改變,自動生成與更新菜單。
可以正確響應微信發送的Token驗證,方便快捷。
11. 完全無侵入的MVC模式
使用本框架,不會對SpringMvc自己原生的Mapping產生任何影響,也不會佔用任何獨有的Mapping關係(除了認證請求)。在此框架存在的情況下,你可以使用任何SpringMvc的原生功能,包括根目錄的請求,也不會被微信服務器獨自佔用。
12. 微信Web認證攔截器與URL自動轉換
提供微信OAUTH2認證攔截,通過配置wx.mvc.interceptor.includePatterns和wx.mvc.interceptor.excludePatterns來配置攔截的目標地址,你可以提供一個WxOAuth2Callback接口的實現類作為Bean,在WxOAuth2Interceptor中會自動注入這個bean,並在微信Web認證通過後調用after(WxOAuth2Context context)方法把相關的context傳遞給該Bean的方法,你可以在該方法中獲取到context了的WxWebUser,並通過WxUserManager把WxWebUser轉換為WxUser。關係詳細信息請參考:微信網頁授權。
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
附加功能:自動判斷消息中的url是否需要添加OAuth重定向,請參考WxRedirectUtils。
五、相關鏈接
- JavaDocs
- 微信公眾號開發文檔
- OSChina倉庫
- Github
六、暫時不支持的功能
1. 自定義客服回覆消息
之後可以加入支持,使用註解定義消息客服,類似於@RabbitListener的方式
2. 消息加解密
沒有想到好的方式把消息加解密融合到SpringMvc中
3. 個性化菜單
稍微有點麻煩,用戶分類
4. 高級用戶管理
用戶分組什麼的是否有好的實現?暫時沒有需求
如支付等
6. 待優化:WxMediaStore
七、更新日誌
0.0.1-SNAPSHOT
初始版本
0.1.0-SNAPSHOT:
- 加入WxSession,類似HttpSession,默認實現中sessionId是fromUserName。如果自行提供WxSessionManager的實現類bean,則會使用你的Bean作為manager,默認實現是基於內存的,請自行擴展。
- 優化WxRequest,原始版本為直接把微信請求內容作為Request,更新為WxRequest為微信服務器請求的包裝,內部的body屬性為微信服務器請求體。
- 拆分不同的消息請求體
0.1.1-SNAPSHOT:
優化消息參數綁定,新增指定消息體綁定,參考WxRequestBody
0.1.2.SNAPSHOT & 0.1.2.alpha
上傳maven中央倉庫,生成javadoc,以及一系列規範化
閱讀更多 程序員之言 的文章