1. 程式人生 > >微信公眾號Java接入demo

微信公眾號Java接入demo

微信公眾號Java接入demo

前不久買了一臺服務,本來是用來當梯子用的,後來買了一個域名搭了一個部落格網站,後來不怎麼在上面寫部落格一直閒著,最近申請了一個微信公眾號就想著弄點什麼玩玩。週末沒事就鼓搗了下微信公眾號的接入。
準備工作

一臺能用域名訪問的伺服器
一個微信公眾號
給伺服器裝上jdk、tomcat、ftp、shell工具

編碼

登入測試公眾號後臺,獲取appId和appSecret,新建一個配置檔案來儲存ppId和appSecret,也可以直接寫在程式碼裡,個人不建議這麼寫,在專案中經常會用到一些常量或者說是資源配置,比如要接入其他公司推給你的資料,會給你介面地址、驗證碼什麼的統一建一個配置檔案存放會比較好一點,在以後的頻繁的修改中就會凸顯出重要性,從軟體的結構來看也比較清晰。
-新建一個servlet,編寫程式碼,下面圖片是微信公眾號的基本配置介面,在下圖的url 上填寫你伺服器用來接受微信驗證的url,url必須以http://或https://開頭,分別支援80埠和443埠。用來接收微信訊息和事件介面的urltoken隨便填寫,加密方式我選擇了安全模式,
這裡寫圖片描述
先貼程式碼,本人文件水平有限:
這是一個servlet檔案,用來處理微信發過來的認證請求;

package myservlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class MyServlet
*/
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
boolean isSuccess = CheckUtil.check(signature, timestamp, nonce);
if(isSuccess) {
pw.print(echostr);
pw.write("接入成功!");
}
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

驗證方法


/**
* @Title: CheckUtil.java
* @Package myservlet
* @Description: TODO(用一句話描述該檔案做什麼)
* @author wjk
* @date 2018年7月5日
* @version V1.0
*/

package myservlet;

import java.util.Arrays;

/**
* @ClassName: CheckUtil
* @Description: TODO(這裡用一句話描述這個類的作用)
* @author wjk
* @date 2018年7月5日
*
*/

public class CheckUtil {

public static final String token ="##";

public static boolean check(String signature,String timestamp,String nonce ) {
String arrs[] = {token,timestamp,nonce};
Arrays.sort(arrs);//字典排序
//拼接字串
StringBuffer sb = new StringBuffer();
for(String str :arrs) {
sb.append(str);
}
String signaturesha1 = Sha1Util.encode(sb.toString());
return signaturesha1.equals(signature);
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

sha1加密

package myservlet;

import java.security.MessageDigest;

public final class Sha1Util {

private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
'e', 'f' };

/**
*
* @Title: getFormattedText
* @Description: TODO(這裡用一句話描述這個方法的作用)
* @param @param bytes
* @param @return 引數
* @return String 返回型別
* @throws
*/
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
// 把密文轉換成十六進位制的字串形式
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}

/**
*
* @Title: encode
* @Description: TODO(這裡用一句話描述這個方法的作用)
* @param @param str
* @param @return 引數
* @return String 返回型別
* @throws
*/
public static String encode(String str) {
if (str == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
messageDigest.update(str.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<servlet>
<!--servlet名稱,可以自定義-->
<servlet-name>MyServlet</servlet-name>
<!-- servlet類名: 包名+簡單類名-->
<servlet-class>myservlet.MyServlet</servlet-class>
</servlet>

<servlet-mapping>
<!--servlet名稱,應與上面的名稱保持一致,因為是通過下面的servlet訪問名稱來定位到上面的servlet名稱,再通過上面的名稱定位到servlet類的位置-->
<servlet-name>MyServlet</servlet-name>
<!-- servlet的訪問名稱: /名稱 -->
<url-pattern>/helloMyServlet.do</url-pattern>
</servlet-mapping>
</web-app>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

原理

將token,timestamp,nonce進行字典排序,拼接成一個字串。
將字串進行sha1加密。
將加密後的字元創和signature比較。true則提交成功,請原樣返回echostr引數內容;false則為失敗。