由於微信那邊須要咱們提供一個外網能訪問的地址給它使用,而爲了方便開發,我這裏使用了ngrok
配置外網地址直接指向我本機的地址html
1.到http://natapp.cn//#download下載ngrok。java
2.打開cmd,切換到解壓的目錄,運行ngrok -config ngrok.cfg -subdomain fengzp 8080命令,其中'fengzp'是我本身定義的域名,8080是指向的端口。web
3.運行結果。數組
訪問微信公衆號註冊地址,註冊一個測試公衆號,登錄。安全
在微信公衆平臺開發者文檔上,關於公衆號接入這一節內容在接入指南上寫的比較詳細的,文檔中說接入公衆號須要3個步驟,分別是:服務器
一、填寫服務器配置
二、驗證服務器地址的有效性
三、依據接口文檔實現業務邏輯微信
其實,第3步已經不能算作公衆號接入的步驟,而是接入以後,開發人員能夠根據微信公衆號提供的接口所能作的一些開發。app
第1步中服務器配置包含服務器地址(URL)、Token和EncodingAESKey。微信公衆平臺
服務器地址即公衆號後臺提供業務邏輯的入口地址,目前只支持80端口,以後包括接入驗證以及任何其它的操做的請求(例如消息的發送、菜單管理、素材管理等)都要從這個地址進入。接入驗證和其它請求的區別就是,接入驗證時是get請求,其它時候是post請求;dom
Token可由開發者能夠任意填寫,用做生成簽名(該Token會和接口URL中包含的Token進行比對,從而驗證安全性);
EncodingAESKey由開發者手動填寫或隨機生成,將用做消息體加解密密鑰。本例中所有以未加密的明文消息方式,不涉及此配置項。
第2步,驗證服務器地址的有效性,當點擊「提交」按鈕後,微信服務器將發送一個http的get請求到剛剛填寫的服務器地址,而且攜帶四個參數:
接到請求後,咱們須要作以下三步,若確認這次GET請求來自微信服務器,原樣返回echostr參數內容,則接入生效,不然接入失敗。
1. 將token、timestamp、nonce三個參數進行字典序排序
2. 將三個參數字符串拼接成一個字符串進行sha1加密
3. 開發者得到加密後的字符串可與signature對比,標識該請求來源於微信
實際代碼:編寫一個servlevt,在其中的doGet方法中定義校驗方法,具體代碼以下:
package com.feng.web.service.servlet; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.feng.web.model.WxMessage; import com.feng.web.service.util.BeanUtil; import com.feng.web.service.util.WxMsgUtil; /** * * @author fengzp * */ @WebServlet(urlPatterns = "/WxServlet") public class WxServlet extends HttpServlet { /** * */ private static final long serialVersionUID = -6008816817887502362L; /** * Token可由開發者能夠任意填寫,用做生成簽名(該Token會和接口URL中包含的Token進行比對,從而驗證安全性) */ private final String TOKEN = "fengzp"; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("開始校驗簽名"); /** * 接收微信服務器發送請求時傳遞過來的4個參數 */ String signature = request.getParameter("signature");// 微信加密簽名signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。 String timestamp = request.getParameter("timestamp");// 時間戳 String nonce = request.getParameter("nonce");// 隨機數 String echostr = request.getParameter("echostr");// 隨機字符串 System.out.println(signature); System.out.println(timestamp); System.out.println(nonce); System.out.println(echostr); // response.getWriter().print(echostr); // 加密 String mySignature = sha1(sort(TOKEN, timestamp, nonce)); // 校驗簽名 if (mySignature != null && mySignature != "" && mySignature.equals(signature)) { System.out.println("簽名校驗經過。"); response.getWriter().write(echostr); // response.getWriter().print(echostr); } else { System.out.println("簽名校驗失敗."); } } public 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(); } private 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 ""; } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
而後進入微信測試公衆號管理界面,在接口配置信息中的URL填寫這個servlet的外網地址和咱們自定義的token,以下圖所示:
到此咱們的微信公衆號已接入完畢。