隨着移動互聯網愈來愈普及,衆多企業都註冊了微信公衆號,因而微信公衆號的開發也愈來愈多,爲了避免被世界所淘汰,特意學習下微信公衆號的開發,已備不時之需!html
按照慣例,學習一門新技術或者新框架,我們仍是從官方提供的文檔開始,因而找到微信公衆平臺開發者文檔(http://mp.weixin.qq.com/wiki/home/index.html)redis
一、微信公衆平臺接口測試號申請json
按照文檔指引,我們得先申請一個微信公衆平臺接口測試帳號(http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login),使用本身我的的微信掃一掃受權便可申請成功,申請成功後發現微信會爲咱們自動分配一個微信號、appID和appsecret(以下圖所示)。api
二、本地服務器地址外網映射數組
開發基於微信公衆號的應用最大的痛苦之處就是調試問題,每次實現一個功能後都須要部署到一個公網服務器進行測試,由於微信用戶每次向公衆號發起請求時,微信服務器會先接收到用戶的請求,而後再轉發到咱們的服務器上,也就是說,微信服務器是要和咱們的服務器進行網絡交互,因此咱們必須保證咱們的服務器外網能夠訪問到,這種部署到公網服務器進行測試的作法對於咱們開發者來講簡直是噩夢。因此咱們要想一個辦法能夠作到本地部署,本地調試代碼,而要作到這一點,那麼咱們要解決的問題就是將內網的部署服務器映射到外網,讓微信服務器能夠正常訪問到,幸運的是,藉助於第三方軟件Ngrok,咱們就能夠作獲得。Ngrok是一個免費的軟件Ngrok,使用Ngrok後,咱們就能夠實現內網穿透,也就是說咱們能夠將內網的服務器映射到外網給別人訪問,這對於咱們在本地開發環境中調試微信代碼是以及給用戶演示一些東西很是快速和有幫助的,由於能夠直接使用咱們本身的內網的電腦做爲服務器。緩存
國內提供Ngrok服務比較好的網站是:http://natapp.cn/,下載到本地解壓後運行natapp.exe文件便可。固然,因爲使用的是免費版,這裏默認映射地址爲:127.0.0.1:80,外網地址則隨機生成,若是選擇付費能夠自定義二級域名,下面是我映射的狀況:服務器
三、接入微信公衆平臺開發微信
按照文檔指引,接下來能夠進行微信公衆平臺開發接入了,接入步驟以下:網絡
第一步:填寫服務器配置,也就是URL和Token,URL就是服務器接口地址,Token自定義app
第二步:驗證服務器地址的有效性,當點擊「提交」按鈕後,微信服務器將發送一個http的get請求到剛剛填寫的服務器地址,而且攜帶四個參數及加密/校驗流程:
第三步:依據接口文檔實現業務邏輯,以下所示:
@RequestMapping("/token") public void token(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) throws IOException{ //微信加密簽名signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。 String signature = request.getParameter("signature"); //時間戳 String timestamp = request.getParameter("timestamp"); //隨機數 String nonce = request.getParameter("nonce"); //隨機字符串 String echostr = request.getParameter("echostr"); //排序 String sortString = WechatUtil.sort(TOKEN, timestamp, nonce); //加密 String mySignature = WechatUtil.sha1(sortString); //校驗簽名 if (mySignature != null && mySignature != "" && mySignature.equals(signature)) { System.out.println("success"); //若是檢驗成功輸出echostr,微信服務器接收到此輸出,纔會確認檢驗完成。 response.getWriter().write(echostr); } else { System.out.println("fail"); } } /** * 排序 * @param token * @param timestamp * @param nonce * @return */ public static String sort(String token, String timestamp, String nonce) { String[] strArray = {token, timestamp, nonce}; Arrays.sort(strArray); StringBuilder sb = new StringBuilder(); for (String str : strArray) { sb.append(str); } return sb.toString(); } /** * sha1加密 * @param str * @return */ public static String sha1(String str) { try { MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.update(str.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); // 字節數組轉換爲 十六進制 數 for (int i = 0; i < messageDigest.length; i++) { String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); if (shaHex.length() < 2) { hexString.append(0); } hexString.append(shaHex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; }
按要求填寫URL和Token,點擊「提交」按鈕後便可配置成功:
四、access_token管理
關於access_token的獲取方式,在微信公衆平臺開發者文檔上有說明,公衆號能夠調用一個叫"獲取access token"的接口來獲取access_token。
獲取access token接口調用請求說明
http請求方式: GET
請求的URL地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
因爲access_token天天最多請求2000次,每次超時時間爲7200秒,所以必須採起每種策略來獲取access_token,方法有不少種,這裏我採起的是藉助redis服務器來緩存access_token的方式(利用redis緩存服務器緩存數據時能夠設置超時時間的特性),具體代碼以下:
public String obtain() { String accessToken = ""; String url = MessageFormat.format(baseUrl, appId, appSecret); String responseStr = HttpClientUtil.get(url); Jedis jedis = redisService.borrow(); try { if(jedis.exists(WechatConst.WECHAT_ACCESS_TOKEN)){ accessToken = jedis.get(WechatConst.WECHAT_ACCESS_TOKEN); }else{ AccessTokenResponseDTO dto = JsonUtil.json2Bean(responseStr, AccessTokenResponseDTO.class); accessToken = dto.getAccess_token(); jedis.setex(WechatConst.WECHAT_ACCESS_TOKEN, 7000, accessToken); } } catch (Exception e) { log.debug("[wechat]accessToken response parse error[response="+responseStr+"]"); e.printStackTrace(); } finally{ redisService.returnResource(jedis); } return accessToken; }
至此,關於微信公衆號開發的基礎工做已基本完成,萬丈高樓平地起,接下來能夠進行具體的開發了。
----------------------------------------------------------------------------------------------------------------------------
ps:除了代碼以外,咱還能夠聊點別的,有興趣能夠關注個人我的微信公衆號!