微信公眾號開發前准備
一、提供外網地址
因為微信那邊需要我們提供一個外網能訪問的地址給它使用,而為了方便開發,我這里使用了ngrok
配置外網地址直接指向我本機的地址
1.到http://natapp.cn//#download下載ngrok。
2.打開cmd,切換到解壓的目錄,運行ngrok -config ngrok.cfg -subdomain fengzp 8080命令,其中'fengzp'是我自己定義的域名,8080是指向的端口。
3.運行結果。
二、接入微信公眾號
注冊公眾號
訪問微信公眾號注冊地址,注冊一個測試公眾號,登陸。
微信公眾號接入
在微信公眾平台開發者文檔上,關於公眾號接入這一節內容在接入指南上寫的比較詳細的,文檔中說接入公眾號需要3個步驟,分別是:
1、填寫服務器配置
2、驗證服務器地址的有效性
3、依據接口文檔實現業務邏輯
其實,第3步已經不能算做公眾號接入的步驟,而是接入之后,開發人員可以根據微信公眾號提供的接口所能做的一些開發。
第1步中服務器配置包含服務器地址(URL)、Token和EncodingAESKey。
服務器地址即公眾號后台提供業務邏輯的入口地址,目前只支持80端口,之后包括接入驗證以及任何其它的操作的請求(例如消息的發送、菜單管理、素材管理等)都要從這個地址進入。接入驗證和其它請求的區別就是,接入驗證時是get請求,其它時候是post請求;
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,如下圖所示:
到此我們的微信公眾號已接入完畢。