首先,需要寫一個java的web程序,寫一個servlet,完成對微信服務器發送驗證請求的響應。
package com.jxq.weixin.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Signature extends HttpServlet {
//token
private final String token = "fengzheng";
/**
* Constructor of the object.
*/
public Signature() {
super();
}
/**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("微信公衆號,開始簽名校驗");
String signature = request.getParameter("signature")==null?"":request.getParameter("signature").toString();
String timestamp = request.getParameter("timestamp")==null?"":request.getParameter("timestamp").toString();
String nonce = request.getParameter("nonce")==null?"":request.getParameter("nonce").toString();
String echostr = request.getParameter("echostr")==null?"":request.getParameter("echostr").toString();
ArrayList<String> array = new ArrayList<String>();
array.add(signature);
array.add(timestamp);
array.add(nonce);
//原理:微信服務器發送上述4個參數給自己的程序,由自己的程序按照算法生成加密字符串,與微信服務器傳過來的簽名進行比對。
//如果相同,則返回微信服務器結果。把echostr參數的內容原封不動回傳微信服務器。雙方完成握手,即表示對接成功。
//使用微信服務器發過來的timestamp,nonce參數和自定義的token組合,使用sha1加密算法生成字符串,然後與微信服務器發過來的signature參數進行比對。
//排序,
String sortString = sort(token, timestamp, nonce);
//加密
String mytoken = SHA1(sortString);
//校驗簽名
if (mytoken != null && mytoken != "" && mytoken.equals(signature)) {
System.out.println("微信公衆號,簽名校驗通過。");
response.getWriter().println(echostr); //如果檢驗成功輸出echostr,微信服務器接收到此輸出,纔會確認檢驗完成。
} else {
System.out.println("微信公衆號,簽名校驗失敗。");
}
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.print(" This is ");
out.print(this.getClass());
out.println(", using the POST method");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
// Put your code here
}
/**
* 排序方法
* @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 sbuilder = new StringBuilder();
for (String str : strArray) {
sbuilder.append(str);
}
return sbuilder.toString();
}
public static String SHA1(String decript) {
try {
MessageDigest digest = MessageDigest
.getInstance("SHA-1");
digest.update(decript.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 "";
}
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>Signature</servlet-name>
<servlet-class>com.jxq.weixin.servlet.Signature</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Signature</servlet-name>
<url-pattern>/servlet/Signature</url-pattern>
</servlet-mapping>
</web-app>
需要把上述程序部署在公網上,端口爲80.這裏用tomcat服務器,申請的華爲雲平臺服務器。
其次,登錄微信公衆號平臺,在接口配置信息中,設置自己部署的web服務器的servlet訪問路徑和自己在servlet中定義的token。點擊提交。
此時微信服務器會向自己的服務器發起請求,並傳遞signature,tiemstamp,nounce和echostr參數。自己服務器收到請求後,需要對timestamp,nounce,自定義的token三個參數進行sha1加密,然後與傳過來的signature對比,如果相同,雙方握手成功,自己的服務器將原來收到的echostr返回給微信服務器即可。
此時,微信公衆號平臺纔會提示配置成功。否則,如果自己的服務器不原樣返回收到的echo參數內容,微信服務器不會提示配置成功。
至此,即可進行後續的微信開發了。
參數 描述
signature 微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。
timestamp 時間戳
nonce 隨機數
echostr 隨機字符串
配置界面參數如下圖,其中Signature是部署在自己服務器上的Servlet,用於對微信服務器的驗證請求進行驗證和返回信息。Token是在Signature 的java中自己定義的字符串。