轉載請標明出處<http://blog.csdn.net/bingtianxuelong/article/details/17843111>,謝謝!.
版本說明:
    V1: 
2014-2-13更新,紅色字型代表最近一次更新的內容。
    V2:
            2014-3-30  更新,上一版本有很多讀者反應說最後還是無法通過微信 token 認證,此版本特意解決這個問題。紅色字型代表最近一次更新的內容。
至讀者:
    對於版本 v1 不能成功的問題,我對此深表歉意,版本 v2 通過我再三測試,肯定能通過微信的 token,版本 v1 不能不能成功的問原因是 eclipse 新建的工程不對, 導致部署不成功,讀者可以留意一下這裡。另外,要特意感謝一位朋友,他通過遠端協助給我演示了一遍,才能讓我把問題給解決了,同時還要感謝那些信任和支援我的朋友,感謝那些向我反映問題的讀者。
前言: 
因為要進行微信開發,就必須要成為微信開發者,要想成為微信開發者,就必須要有伺服器響應微信的 Token 驗證,如果沒有公網伺服器環境,可以去了解下BAE、SAE或阿里雲,這裡以 BAE 為例。
前提條件:
   (1)擁有微信公眾平臺帳號(申請地址:https://mp.weixin.qq.com/)
     (2)擁有百度BAE開發者帳號(申請地址:http://developer.baidu.com/)
   (3)搭建好 Java 開發環境,沒有搭建好的可參考Java 開發環境搭建
準備工作:
下載一個整合好BAE開發環境的eclipse(也可以線上安裝外掛),在百度網頁(http://developer.baidu.com/wiki/index.php?title=docs/cplat/ide/install)最下面有一鍵安裝那裡下載,這是已預裝了Baidu Eclipse外掛以及 svn 版本管理工具的Eclipse安裝包,下載到本地解壓即可用(有可能首次啟動會報錯 Eclipse is running in a JRE, but a JDK is required, 解決方法,點此進入)。非常簡單,不建議自己安裝外掛,除非你很熟悉怎麼去安裝。
如果你已經有了 MyEclipse 工具,那麼,恭喜你,你不需要安裝 Baidu Eclipse 也可以搭建一個開發環境,具體操作,請看另外一篇部落格。
步驟:
1、去BAE快速建立一個JAVA應用

                                        圖 1
    點選 “建立應用” 填上應用名稱,點選“儲存”,如圖2

                                       圖 2
    你就會看到你建立好的應用:(圖 3)

                                                  圖 3
2、新增部署
點選應用圖示,檢視應用資訊,點選“應用引擎” 彈出“部署列表”頁面:圖 4

                                               圖 4
    點選“新增部署”,按要求填寫,型別選擇 Java-tomcat:圖5

                                                                               圖 5
 建立失敗並提示警告,由於 bae 升級到 3.0 版本,實行分批制度,看公告:圖 6

                                            圖 6
        很悲劇,如果你沒有搶到執行單元,那你就只能等搶到再說,否則你就無法部署你的程式碼。
        檢視部署:BAE部署建立成功後,在部署列表中可看到剛建立的部署資訊。
        注意:程式碼版本工具支援:svn和git,建議選擇 svn 因為這樣比較省事。
3、通過 SVN 檢入工程
    在 bae 上的應用新增部署成功後,如圖 7
                                                     圖 7
    點選“點選檢視”按鈕,會開啟一個新頁面,頁面上會列印 “hello world” ,這是因為我們的應用包含有示例程式碼,也就是基礎工程,我們要將這個工程匯出到本地,然後新增我們自己的程式碼,我們點選“點選複製”複製 svn 的地址備用。
    啟動我們安裝好的 Eclipse, 點選 File -->new --> other,從彈出的視窗中選擇 svn,如圖 8

                                    圖 8
   點選 “從 SVN檢出專案” --> Next -->  建立新的資源庫位置 --> Next --> 貼上剛才複製的 SVN 的地址 --> 點選顯示的地址 Next --> 驗證後會看到檢測出的專案,如圖 9

圖 9
    點選選中專案 --> Next --> 選中“做為新專案檢出,***”,如圖 10

圖 10
    點選 “Finish”,彈出頁面中選擇 “Yes” ,如圖 11

圖 11
注意:選擇 “Yes”後,如果要百度驗證,記得填寫有 user 時不能是中文,如果你的百度賬號是中文登入,趕緊去賬號裡關聯手機號或者Email,這樣你就可以通過手機號或者 Email 來登入百度了。
(往下比更新前變動很大,各位多留意)
在彈出的新建專案嚮導對話方塊中選擇  Web --> Dynamic Web project (動態 web 工程),( 注意不要選擇 Baidu --> BAE Project ,版本 v1 叫大家選擇BAE Project 會發現很難打包) 如圖12:

圖 12
    接著會彈出一個程序框,如圖13:

                                                                   圖 13
    然後在彈出的視窗中填上你的專案名稱,如圖 14:

                                                                     圖 14
    在彈出的視窗中選 Next,彈出如下視窗:

    注意要選中複選框,生成 web.xml 檔案,  點選 “Finish”按鈕,如果彈出如圖15 所示對話方塊:
                                                                                       圖 15
    點選“OK”按鈕,接著就是等待檢出專案。
    成功檢出來的專案是預設已經連線了 svn 的,並且不會報錯,有報錯的話,請留言聯絡我。
4、在工程中新增程式碼,讓其響應微信驗證
    檢視我們的工程,如圖 17

圖 17
    新建一個 servlet 包,方法是:"src" --> 右鍵 --> new --> packages, 命名隨意,例如 org.ivy.course.servlet,如圖:

往包裡新增一個能夠處理請求的Servlet 類,這次我採用嚮導的方式新增,如圖所示:

點選圖中的 “Create a new Servlet ” ,在彈出視窗中填上類名 CoreServlet :

點選 Next,注意彈出的視窗中的 URL mappings,訪問時要用到它:

點選 Next 後點擊 “Finish”得到通過嚮導新建的類 CoreServlet:
package org.ivy.course.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Servlet implementation class CoreServlet
 */
@WebServlet("/CoreServlet")
public class CoreServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    /**
     * Default constructor. 
     */
    public CoreServlet() {
        // TODO Auto-generated constructor stub
    }
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }
}


新建的類 Servlet 可能會報錯,同時匯入的標頭檔案也會報錯,如圖:

這是因為缺少 servlet-api.jar 這個包,網路上下載這個包,新增到工程中就行了,做法是直接複製這個包,然後再工程的 WebContent/WEB-INF/Lib 中右鍵選擇 Paste 貼上進去並右鍵重新整理工程就行了,實在不行,請參考我的部落格 【The import javax.servlet cannot be resolved 解決方法】。
我們在 doGet 方法中新增我們的程式碼,完整如下:
package org.ivy.course.servlet;

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

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.ivy.course.util.SignUtil;

/**
 * Servlet implementation class CoreServlet
 */
@WebServlet("/CoreServlet")
public class CoreServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * Default constructor. 
     */
    public CoreServlet() {
        // TODO Auto-generated constructor stub
    }

    /**
     * 確認請求來自微信伺服器
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        
        // my
        // 微信加密簽名
        String signature = request.getParameter("signature");
        // 時間戮
        String timestamp = request.getParameter("timestamp");
        // 隨機數
        String nonce = request.getParameter("nonce");
        // 隨機字串
        String echostr = request.getParameter("echostr"); 
        
        PrintWriter out = response.getWriter();
        // 通過檢驗 signature 對請求進行校驗,若校驗成功則原樣返回 echostr,表示接入成功,否則接入失敗
       if(SignUtil.checkSignature(signature, timestamp, nonce)){
           out.print(echostr);
       }

       out.close();
       out = null;        
    }

    /**
     * 處理微信伺服器發來的訊息 
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        // 訊息的接收、處理、響應  
    }

}

在doGet方法中呼叫了checkSignature方法,該方法還沒有實現,我們新建一個包 org.ivy.course.util 作為一個工具包,並往該包中新增新類 SignUtil,新增類的方法是:包名右鍵 -->new --> class,填上類名,其它預設,完整程式碼如下:
package org.ivy.course.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

public class SignUtil {
    /**
     * 與介面配置資訊中的 token 要一致,這裡賦予什麼值,在介面配置資訊中的Token就要填寫什麼值,
     * 兩邊保持一致即可,建議用專案名稱、公司名稱縮寫等,我在這裡用的是專案名稱weixinface
     */
    private static String token = "weixinface";
    
    /**
     * 驗證簽名
     * @param signature
     * @param timestamp
     * @param nonce
     * @return
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce){
        String[] arr = new String[]{token, timestamp, nonce};
        // 將 token, timestamp, nonce 三個引數進行字典排序
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for(int i = 0; i < arr.length; i++){
            content.append(arr[i]);
        }
        MessageDigest md = null;
        String tmpStr = null;
        
        try {
            md = MessageDigest.getInstance("SHA-1");
            // 將三個引數字串拼接成一個字串進行 shal 加密
            byte[] digest = md.digest(content.toString().getBytes());
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        content = null;
        // 將sha1加密後的字串可與signature對比,標識該請求來源於微信
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()): false;
    }
    
    /**
     * 將位元組陣列轉換為十六進位制字串
     * @param digest
     * @return
     */
    private static String byteToStr(byte[] digest) {
        // TODO Auto-generated method stub
        String strDigest = "";
        for(int i = 0; i < digest.length; i++){
            strDigest += byteToHexStr(digest[i]);
        }
        return strDigest;
    }
    
    /**
     * 將位元組轉換為十六進位制字串
     * @param b
     * @return
     */
    private static String byteToHexStr(byte b) {
        // TODO Auto-generated method stub
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(b >>> 4) & 0X0F];
        tempArr[1] = Digit[b & 0X0F];
        
        String s = new String(tempArr);
        return s;
    }
}

程式碼新增完畢,工程右鍵,刪除工程中的 ROOT.war 包,  然後工程右鍵重新打包一個 ROOT.war 包,名字必須和原來一樣,儲存地址也和原來一樣,具體是,右鍵 -->  Export --> WAR file:


匯出後,專案右鍵重新整理工程,包 ROOT.war 就會重新出現在工程中,然後我們提交我們的工程到百度 BAE 上就行了,具體做法看下面。
5、提交修改後的程式碼
    工程右鍵 --> Team --> 提交 --> ok, 如圖 18

圖 18
如果要驗證,就輸入你的百度賬號密碼,提交成功後,部署列表狀態列會顯示“有新版”,此時點選“快捷釋出”也等同上線。如圖 19 所示:

 圖 19
    釋出後,點選檢視,在彈出頁面的地址中新增上面叫你記住的那個 URL mappings,如果你沒有改過,預設是“/CoreServlet”,如果你 實在忘了,可以到你的類CoreServlet 中找到這個語句:@WebServlet("/CoreServlet"),就是這個字尾,舉個例子,例如你點選檢視的網站是  < http://weitest.duapp.com >  ,新增字尾後的地址是 < http://weitest.duapp.com/CoreServlet > 填完網址後回車,就能看到如下頁面:

看到此畫面就說明你離成功只差一步了,記住複製此網頁的地址備用。
6、成為微信開發者
    開啟微信公眾平臺 -> 高階功能 -> 開發者模式,見圖 20:
    圖20
將我們剛才複製的地址黏貼到 URL ;
在填寫 Token 之前,也回到我們的專案,在類 SignUtil 中有這麼一句程式碼:
private static String token = "weixinface";

程式碼中的 token 的值我們可以隨意寫,但是,這裡是什麼值,在微信平臺上就要填寫對應的內容,所有,在 Token 那裡填上 weixinface,點選“提交”,如果程式碼沒有問題,瞬間你就可以看到“你已成為開發者” 的提示:如圖 22

相關文章
0.001291036605835