微信公衆號開發(一)

微信公衆號開發前準備

1、提供外網地址

由於微信那邊須要咱們提供一個外網能訪問的地址給它使用,而爲了方便開發,我這裏使用了ngrok配置外網地址直接指向我本機的地址html

1.到http://natapp.cn//#download下載ngrok。java

2.打開cmd,切換到解壓的目錄,運行ngrok -config ngrok.cfg -subdomain fengzp 8080命令,其中'fengzp'是我本身定義的域名,8080是指向的端口。web

3.運行結果。數組


2、接入微信公衆號

註冊公衆號

訪問微信公衆號註冊地址,註冊一個測試公衆號,登錄。安全

微信公衆號接入

微信公衆平臺開發者文檔上,關於公衆號接入這一節內容在接入指南上寫的比較詳細的,文檔中說接入公衆號須要3個步驟,分別是:服務器

  一、填寫服務器配置
  二、驗證服務器地址的有效性
  三、依據接口文檔實現業務邏輯微信

其實,第3步已經不能算作公衆號接入的步驟,而是接入以後,開發人員能夠根據微信公衆號提供的接口所能作的一些開發。app

  第1步中服務器配置包含服務器地址(URL)、Token和EncodingAESKey。微信公衆平臺

  服務器地址即公衆號後臺提供業務邏輯的入口地址,目前只支持80端口,以後包括接入驗證以及任何其它的操做的請求(例如消息的發送、菜單管理、素材管理等)都要從這個地址進入。接入驗證和其它請求的區別就是,接入驗證時是get請求,其它時候是post請求;dom

  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,以下圖所示:

到此咱們的微信公衆號已接入完畢。

相關文章
相關標籤/搜索