【Java】微信公眾號開發筆記
GitHub Repository:School-Assistant
一、準備工作
1.微信公眾號的介紹
詳情請看微信公眾平臺開發概述。
2.開發環境的搭建
利用ngrok進行內網穿透,測試是否聯通:在本地內部如果想訪問自己的程式是很容易的,在同一個IP地址下就可以訪問同一個內網(區域網),但是如果不在該內網下的其他的使用者是無法訪問的。內網穿透顧名思義,就是打破這層“隔膜”,讓外面的使用者可以訪問。當然在這個地方的話,這個主要是還是用來測試我們的微信公眾號是不是打通了,傳到伺服器上就不必考慮這些事情了。
內網穿透的原理:傳統的開發的軟體的通訊是網址---伺服器---應用程式,ngrok的作用就是替代這個應用程式,通訊地址換成一個分配好的二級地址,可以直接進行訪問。這樣的話,我們的開發的程式和軟體就可以直接進行通訊。
ngrok如何使用以及下載的地址:Sunny_ngrok,此處不再贅述。這個地方需要注意的是,如果ngrok和tomcat兩個都沒有開的,其他人是無法訪問這個頁面的,所以無需擔心被入侵的問題。開啟之後,輸入sunny clientid xxxxx,這裡的xxxxx就是你的隧道id,當發現狀態為Tunnel Status變成online的時候,就可以了。在MyEclipse中有自帶的tomcat可以使用,把介面調成80即可。
這個地方記錄一下這個ngrok踩過的坑:因為這個地方的tomcat的埠號是8080,但是ngrok卻是一個80埠,所以需要修改一下tomcat的埠號為80埠。MyEclipse中其實自帶著一個tomcat,啟動的時候要注意不要啟動錯了,否則啟動了這個tomcat的話怎麼改都改都改不對。連結:如何去修改tomcat的埠號?
3.開發接入
因為安全問題,微信的諸多功能是無法針對個人使用者開發的,微信針對開發者開放了開發者賬號用來測試介面。地址如下:介面測試號申請。以下是Java程式碼的實現各個功能。
微信打通實現:WxServlet.java
開發者通過檢驗signature對請求進行校驗。若確認此次GET請求來自微信伺服器,請原樣返回echostr引數內容,則接入生效,成為開發者成功,否則接入失敗。
package servlet;
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;
import service.WxService;
public class WxServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
//登陸驗證:如果接入成功原樣返回一個數值//
if(WxService.check(signature , timestamp , nonce)){
//System.out.println("接入成功");
PrintWriter out = response.getWriter();
out.print(echostr);
out.flush();
out.close();
}
else{
System.out.println("接入失敗");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("post");
}
}
sha1檢驗演算法類:WxService.java
第一步:將token、timestamp、nonce三個引數進行字典序排序。 第二步:將三個引數字串拼接成一個字串進行sha1加密 。第三步:開發者獲得加密後的字串可與signature對比,標識該請求來源於微信。(暫時開坑sha1演算法,這個地方值得學一下。在Java中已經有了MessageDigest這個類了,所以可以直接進行使用。sha1是一個加密演算法,把數值轉換成Byte型,然後進行16位的轉換。)
package service;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class WxService {
//微信服務的驗證簽名:
private static final String TOKEN = "bonstop";//這裡的Token的數值必須和微信開發的配置方式一致//
private static String sha1(String s){ // 加密方法//
try{
//獲取一個加密的物件//
MessageDigest md = MessageDigest.getInstance("sha1");
//加密//
byte[] digest = md.digest(s.getBytes());
char[] chars = {'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f'};
StringBuilder sb = new StringBuilder();
//處理加密的結果//
for(byte b : digest)
{
sb.append(chars[(b >> 4) & 15]);//取其高四位//
sb.append(chars[b & 15]);//取其低四位//
}
return sb.toString();
}
catch(NoSuchAlgorithmException e){
e.printStackTrace();
}
return null;
}
public static boolean check(String signature , String timestamp , String nonce){
//1)將token、timestamp、nonce三個引數進行字典序排序
String[] str = new String[] {TOKEN , timestamp , nonce};
Arrays.sort(str);
//2)將三個引數字串拼接成一個字串進行sha1加密
String s = str[0] + str[1] + str[2];
String mysig = sha1(s);
System.out.println(mysig);
System.out.println(signature);
//3)開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
return mysig.equalsIgnoreCase(signature);
}
}
微信使用者發訊息樣例:test.xml
這個是我從手機上傳送一個“”得到的結果。拉取來自一個使用者的訊息。
<xml>
<!--
ToUserName : 開發者微訊號
FromUserName : 傳送方帳號(一個OpenID : 只是隨機放的一個資料)
CreateTime : 訊息建立時間 (整型)單位時間為秒
MsgType : 訊息型別,文字為text
Content : 文字訊息內容
MsgId : 訊息id,64位整型
-->
<ToUserName><![CDATA[gh_c67e59e8f8c6]]></ToUserName>
<FromUserName><![CDATA[oBzBC1Qwf-7-nxXs6ghXCrrxK13A]]></FromUserName>
<CreateTime>1554984695</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[浣犲ソ]]></Content><!-- 我發了一個“你好”,這個需要後序做一個解析才能使用 -->
<MsgId>22262029333601665</MsgId>
</xml>
Day2:接入使用者訊息
接入使用者訊息:WxServlet.Java
Post可以接入從微信上發過來的訊息。
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import service.WxService;
public class WxServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
//登陸驗證:如果接入成功原樣返回一個數值//
if(WxService.check(signature , timestamp , nonce)){
//System.out.println("接入成功");
PrintWriter out = response.getWriter();
out.print(echostr);
out.flush();
out.close();
}
else{
System.out.println("接入失敗");
}
}
/*
* doPost用來接收訊息和事件的推送
* */
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//處理訊息和事件推送
Map<String , String> requestMap = WxService.parseRequest(request.getInputStream());
System.out.println(requestMap);
}
}
新增parseRequest 方法:WxService.Java
parseRequest這個功能就是讓XML資訊可以被傳回來。這裡用了dom4j.jar包進行進行解析XML。dom4j.jar放在WebROOT/Web-INF/lib下的檔案內。注意不要下載錯了jar包(dom4j-1.6.1),否則會報錯。下載地址:<dom4j>。
package service;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletInputStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class WxService {
//微信服務的驗證簽名:
private static final String TOKEN = "bonstop";//這裡的Token的數值必須和微信開發的配置方式一致//
private static String sha1(String s){ // 加密方法//
try{
//獲取一個加密的物件//
MessageDigest md = MessageDigest.getInstance("sha1");
//加密//
byte[] digest = md.digest(s.getBytes());
char[] chars = {'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f'};
StringBuilder sb = new StringBuilder();
//處理加密的結果//
for(byte b : digest)
{
sb.append(chars[(b >> 4) & 15]);//取其高四位//
sb.append(chars[b & 15]);//取其第四位//
}
return sb.toString();
}
catch(NoSuchAlgorithmException e){
e.printStackTrace();
}
return null;
}
public static boolean check(String signature , String timestamp , String nonce){
//1)將token、timestamp、nonce三個引數進行字典序排序
String[] str = new String[] {TOKEN , timestamp , nonce};
Arrays.sort(str);
//2)將三個引數字串拼接成一個字串進行sha1加密
String s = str[0] + str[1] + str[2];
String mysig = sha1(s);
System.out.println(mysig);
System.out.println(signature);
//3)開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
return mysig.equalsIgnoreCase(signature);
}
public static Map<String, String> parseRequest(InputStream is) {
Map<String , String> map = new HashMap();
SAXReader reader = new SAXReader();
try{
//讀取輸入流,獲取文件物件//
Document document = reader.read(is);
//根據文件物件獲取根節點//
Element root = document.getRootElement();
//獲取根節點下的所有子節點//
List<Element> elements = root.elements();
for(Element e : elements){
map.put(e.getName(), e.getStringValue());
}
}
catch(DocumentException e){
e.printStackTrace();
}
return map;
}
}
相關文章
- 微信公眾號Java開發記錄(一)接入Java
- 微信公眾號開發
- 微信公眾號支付開發手記(node)
- 記一次微信公眾號開發
- Nodejs微信公眾號開發NodeJS
- .net開發微信公眾號
- 微信公眾號開發-分享
- 微信sdk 公眾號 微信支付 NFC 坑&筆記筆記
- 公眾號開發筆記筆記
- 微信公眾號開發 —— 微信網頁授權小記網頁
- 微信公眾號支付開發全過程(Java 版)Java
- 微信公眾號開發之坑(一)
- Python+Tornado開發微信公眾號Python
- PHP微信公眾號開發——公共方法PHP
- Laravel+easywechat 開發微信公眾號Laravel
- 微信公眾號測試號開發小結
- 微信公眾號自動回覆_JavaJava
- 微信公眾號讚賞功能開通方法 微信公眾號讚賞如何開通
- 微信公眾號支付踩坑記
- 微信公眾號開發推送事件排重事件
- 微信公眾號開發Django JSSDK授權DjangoJS
- 微信公眾號開發(一)基礎配置
- Spring Boot 開發微信公眾號後臺Spring Boot
- 微信公眾號開發之客服訊息
- 微信公眾號開發5-自定義選單-微信開發phpPHP
- 微信開發系列之一 - 微信公眾號開發的開發環境搭建開發環境
- NodeJS介紹以及開發微信公眾號ExampleNodeJS
- Python開發微信公眾號後臺(系列二)Python
- 微信公眾號開發Django 網頁授權Django網頁
- 微信公眾號開發教程(一) 驗證接入
- Nodejs開發微信公眾號中控服務NodeJS
- 微信公眾號開發-後端demo(隨錄)後端
- 微信公眾號智慧回答
- 微信公眾號託管
- 微信公眾號下發紅包 -- PHPPHP
- 【微信部落】tp5+ionic開發微信公眾號商城系統
- 開發微信公眾號基本配置引數錯誤
- 微信公眾號影片直播系統開發介紹