微信公衆號開發(二)—— 微信公衆平臺接入

  在上一篇《微信公衆號開發(一)——環境搭建》中咱們已經準備好了微信公衆號開發環境,那麼接下來咱們要真正的開始進行公衆號的實際開發之旅。html

在真正的開發公衆號以前咱們必需要接入微信公衆平臺,那爲何要接入、如何接入本文就這些問題一一解答;java

首先咱們來了解一下接入平臺的原理,而後再貼出代碼上手實踐測試。web

1、微信公衆平臺的基本原理

微信服務器就至關於一個轉發服務器,終端(手機、Pad等)發起請求至微信服務器,微信服務器而後將請求轉發給咱們的應用服務器。應用服務器處理完畢後,將響應數據回發給微信服務器,微信服務器再將具體響應信息回覆到微信App終端。spring

  通訊協議爲:HTTPjson

  數據傳輸格式爲:XML數組

  具體的流程以下圖所示:安全

  

  來一張更加直觀的圖吧:springboot

  

  咱們須要作的事情,就是對微信服務器轉發的HTTP請求作出響應。具體的請求內容,咱們按照特定的XML格式去解析,處理完畢後,也要按照特定的XML格式返回。服務器

2、微信公衆平臺接入步驟

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

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

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

  第1步中服務器配置包含服務器地址(URL)、Token和EncodingAESKey。

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

  Token可由開發者能夠任意填寫,用做生成簽名(該Token會和接口URL中包含的Token進行比對,從而驗證安全性);

  EncodingAESKey由開發者手動填寫或隨機生成,將用做消息體加解密密鑰。本例中所有以未加密的明文消息方式,不涉及此配置項。

以測試帳號爲例:

  第1步 配置咱們的服務器參數

咱們點擊修改按鈕輸入url和token點擊提交; 

  第2步,驗證服務器地址的有效性,當點擊「提交」按鈕後,微信服務器將發送一個http的get請求到剛剛填寫的服務器地址,而且攜帶四個參數:

  

  接到請求後,咱們須要作以下三步,若確認這次GET請求來自微信服務器,原樣返回echostr參數內容,則接入生效,不然接入失敗。

  1. 將token、timestamp、nonce三個參數進行字典序排序
  2. 將三個參數字符串拼接成一個字符串進行sha1加密
  3. 開發者得到加密後的字符串可與signature對比,標識該請求來源於微信

   第3步  依據接口文檔實現業務邏輯  

  驗證URL有效性成功後即接入生效,成爲開發者。你能夠在公衆平臺網站中申請微信認證,認證成功後,將得到更多接口權限,知足更多業務需求。
  成爲開發者後,用戶每次向公衆號發送消息、或者產生自定義菜單、或產生微信支付訂單等狀況時,開發者填寫的服務器配置URL將獲得微信服務器推送過來的消息和事件,開

  發者能夠依據自身業務邏輯進行響應,如回覆消息。

  公衆號調用各接口時,通常會得到正確的結果,具體結果可見對應接口的說明。返回錯誤時,可根據返回碼來查詢錯誤緣由。全局返回碼說明
  用戶向公衆號發送消息時,公衆號方收到的消息發送者是一個OpenID,是使用用戶微信號加密後的結果,每一個用戶對每一個公衆號有一個惟一的OpenID

 3、代碼示例

  一、首先咱們要建立一個java web 工程

  二、建立一個controller 來進行服務器的驗證

package com.quanlian.controller;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;

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

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import util.NetWorkHelper;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.quanlian.entity.AccessToken;
import com.quanlian.entity.AccessTokenInfo;
import com.quanlian.runner.MyApplicationRunner;


@RestController
public class WxController {
    
    private final String TOKEN = "super";
    @RequestMapping(value="/hello")
    public String hello(){
        return "hello";
    }
    
    @RequestMapping(value = "wx")
    public String wxcheck(HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException {
        String method = request.getMethod();
        System.out.println(method);
        if(method.equals("POST")){
            return wxMessage(request,response);
        }else{
            String signature = request.getParameter("signature");  
            String timestamp = request.getParameter("timestamp");  
            String nonce = request.getParameter("nonce");  
            String echostr = request.getParameter("echostr");  
            System.out.println(echostr);
            //排序
            String sortString = sort(TOKEN, timestamp, nonce);
            //加密
            String mySignature = sha1(sortString);
            if(signature!=null&&signature!=""&&signature.equals(mySignature)){
                System.out.println("簽名校驗經過。");
                return echostr;
            }else{
                System.out.println("簽名校驗失敗.");
                return "xxxx";
            }
        }

    }
    
    @RequestMapping(value="wxMessage",method=RequestMethod.POST)
    public String wxMessage(HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException{
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        System.out.println("請求進入");
        String result = "";
        try {
            Map<String,String> map = MessageHandlerUtil.parseXml(request);
            System.out.println("開始構造消息");
            result = MessageHandlerUtil.buildXml(map);
            System.out.println(result);
            if(result.equals("")){
                result = "未正確響應";
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("發生異常:"+ e.getMessage());
        }
        return result;
    }
    
    /**
     * 排序
     */
    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();
    }
    /**
     * 進行sha1加密
     */
    public 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 "";
        
    }
    
}

  三、啓動咱們的服務,這裏直接運行SpringbootApplication.java就能夠了 我使用的是springboot 有關springboot 的知識請自行百度

  四、運行咱們的natapp.exe 將咱們的服務映射到外網

    

  

  五、將映射的http地址配置到測試帳號中

  

  這裏的 URL必定要保證和natapp中映射的外網地址相匹配;

  六、咱們的服務後臺是打印出以下信息表示咱們的本地服務器配置成功

  

  Ok到這裏本文關於接入服務器的演示完畢!

相關文章
相關標籤/搜索