當初我在這碰到了不少問題,市面上以及網絡上的資料特別少,因此當初碰了不少壁,因此如今跟你們分享一下,如何用Java,對微信公衆平臺進行二次開發。java
1、開發預備知識:算法
最基本的JavaSE與JavaWeb知識:JSP/Servlet/JDBC/EL服務器
2、開發環境微信
Eclipse EE網絡
JDK 1.7(用JDK1.8會報錯!用JDK1.8會報錯!用JDK1.8會報錯!用JDK1.8會報錯!重要的事情說4遍,當初被坑了,愣是不知道錯在哪,檢查了無數遍代碼,就是不知道哪裏錯了)app
3、註冊微信號微信公衆平臺
http://mp.weixin.qq.com/dom
具體過程略,千萬別亂註冊多個,貌似一個身份證只能註冊管理5個微信公衆號。eclipse
4、創建項目ide
一、打開eclipse
二、新建一個 Dynamic Web Project
三、新建一個servlet
package org.hjj.servlet; import java.io.IOException; import java.io.PrintWriter; import java.io.Writer; 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 org.hjj.service.CoreService; import org.hjj.util.CheckUtil; @WebServlet("/wx.do") public class WeixinServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected 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");// 隨機字符串 Writer out = response.getWriter(); System.out.println("收到驗證請求:"); System.out.println(" signature="+signature); System.out.println(" timestamp="+timestamp); System.out.println(" nonce="+nonce); System.out.println(" echostr="+echostr); if(signature==null || timestamp==null || nonce==null || echostr==null){ //這幾個參數爲空時,排序會報錯。 out.write("parameter is null!"); System.out.println("failed"); } else{ if (CheckUtil.checkSignature(signature, timestamp, nonce)) { out.write(echostr);// 請求驗證成功,返回隨機碼 System.out.println("success"); } else { System.out.println("check failed"); out.write("check error!"); } } out.flush(); out.close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); String respXml = CoreService.processRequest(request); out.print(respXml); out.close(); out= null; } }
上面的dopost方法是用來回復消息的,初期能夠不使用,能夠先刪了dopost內的方法
另外在 Util包內編寫驗證和加密邏輯
這個是驗證的邏輯.
package org.hjj.util; import java.util.Arrays; public class CheckUtil { private static final String token="寫你本身的token"; public static boolean checkSignature(String signature,String timestamp,String nonce ){ String [] arr = new String []{token,timestamp,nonce}; Arrays.sort(arr); StringBuffer content = new StringBuffer(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } String temp = SHA1.encode(content.toString()); return temp.equals(signature); } }
加密邏輯我採用的是sha1加密,也很方便,網上有不少案例
package org.hjj.util; import java.security.MessageDigest; /** * <p>Title: SHA1算法</p> * * @author qsyang<yangqisheng274@163.com> */ public final class SHA1 { private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /** * Takes the raw bytes from the digest and formats them correct. * * @param bytes the raw bytes from the digest. * @return the formatted bytes. */ 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(); } 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); } } }
就這三個文件就能夠開啓本身的開發者模式了,
將本身的項目部署到服務器上
URL爲:服務器名+項目名+servlet(我這裏是wx.do)
token本身定義
AESKey本身定義,
而後點肯定就能夠發佈了
咱們工做室租用的是阿里雲服務器,因此部署一下就能夠直接用,固然咱們學生若是沒有服務器條件的,可使用ngrok工具,將本身本地ip映射到公網上去。(找不到博客園的上傳文件功能,同窗們能夠本身去搜)
使用方法是 用cmd把路徑設置到ngrok.exe的目錄下
輸入:ngrok -config ngrok.cfg -subdomain 本身取一個串替換這句話 8080
回車,
本身的ip就到公網上了