(轉)微信公衆平臺開發之基於百度 BAE3.0 的開發環境搭建(採用 Baidu Eclipse)

版本說明:
    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 也能夠搭建一個開發環境,具體操做,請看另一篇博客。
 
步驟:
 
一、去BAE快速建立一個JAVA應用
    去到百度開放雲首頁 ( http://developer.baidu.com/ ),點擊右上角 「管理控制檯」 ,進入個人應用頁面:如圖 1

                                        圖 1
    點擊 「建立應用」 填上應用名稱,點擊「保存」,如圖2

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

                                                  圖 3
 
二、添加部署
    點擊應用圖標,查看應用信息,點擊「應用引擎」 彈出「部署列表」頁面:圖 4

                                               圖 4
 
    點擊「添加部署」,按要求填寫, 類型選擇 Java-tomcat:圖5
 

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

                                            圖 6
 
        很悲劇,若是你沒有搶到執行單元,那你就只能等搶到再說,不然你就沒法部署你的代碼。
        查看部署:BAE部署建立成功後,在部署列表中可看到剛建立的部署信息。
        注意:代碼版本工具支持:svn和git,建議選擇 svn 由於這樣比較省事。
 
三、經過 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 的,而且不會報錯,有報錯的話,請留言聯繫我。
 
四、在工程中添加代碼,讓其響應微信驗證
 
     查看咱們的工程,如圖 17
 
                                     圖 17
 
    新建一個 servlet 包,方法是:"src" --> 右鍵 --> new --> packages, 命名隨意,例如 org.ivy.course.servlet,如圖:
 

 
往包裏添加一個可以處理請求的Servlet 類,此次我採用嚮導的方式添加,如圖所示:
 

 
點擊圖中的 「Create a new Servlet 」 ,在彈出窗口中填上類名 CoreServlet :
 

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

 
點擊 Next 後點擊 「Finish」獲得經過嚮導新建的類 CoreServlet:
 
[java]  view plain copy
 
  1. package org.ivy.course.servlet;  
  2. import java.io.IOException;  
  3. import javax.servlet.ServletException;  
  4. import javax.servlet.annotation.WebServlet;  
  5. import javax.servlet.http.HttpServlet;  
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8. /** 
  9.  * Servlet implementation class CoreServlet 
  10.  */  
  11. @WebServlet("/CoreServlet")  
  12. public class CoreServlet extends HttpServlet {  
  13.     private static final long serialVersionUID = 1L;  
  14.     /** 
  15.      * Default constructor.  
  16.      */  
  17.     public CoreServlet() {  
  18.         // TODO Auto-generated constructor stub  
  19.     }  
  20.     /** 
  21.      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 
  22.      */  
  23.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  24.         // TODO Auto-generated method stub  
  25.     }  
  26.     /** 
  27.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  28.      */  
  29.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  30.         // TODO Auto-generated method stub  
  31.     }  
  32. }  


新建的類 Servlet 可能會報錯,同時導入的頭文件也會報錯,如圖:
 
 
 
這是由於缺乏 servlet-api.jar 這個包,網絡上下載這個包,添加到工程中就好了,作法是直接複製這個包,而後再工程的 WebContent/WEB-INF/Lib 中右鍵選擇 Paste 粘貼進去並右鍵刷新工程就好了,實在不行,請參考 個人博客 【The import javax.servlet cannot be resolved 解決方法 】。
 
  咱們在 doGet 方法中添加咱們的代碼,完整以下:
 
[java]  view plain copy
 
  1. package org.ivy.course.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.annotation.WebServlet;  
  8. import javax.servlet.http.HttpServlet;  
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11.   
  12. import org.ivy.course.util.SignUtil;  
  13.   
  14. /** 
  15.  * Servlet implementation class CoreServlet 
  16.  */  
  17. @WebServlet("/CoreServlet")  
  18. public class CoreServlet extends HttpServlet {  
  19.     private static final long serialVersionUID = 1L;  
  20.   
  21.     /** 
  22.      * Default constructor.  
  23.      */  
  24.     public CoreServlet() {  
  25.         // TODO Auto-generated constructor stub  
  26.     }  
  27.   
  28.     /** 
  29.      * 確認請求來自微信服務器 
  30.      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 
  31.      */  
  32.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  33.         // TODO Auto-generated method stub  
  34.           
  35.         // my  
  36.         // 微信加密簽名  
  37.         String signature = request.getParameter("signature");  
  38.         // 時間戮  
  39.         String timestamp = request.getParameter("timestamp");  
  40.         // 隨機數  
  41.         String nonce = request.getParameter("nonce");  
  42.         // 隨機字符串  
  43.         String echostr = request.getParameter("echostr");   
  44.           
  45.         PrintWriter out = response.getWriter();  
  46.         // 經過檢驗 signature 對請求進行校驗,若校驗成功則原樣返回 echostr,表示接入成功,不然接入失敗  
  47.        if(SignUtil.checkSignature(signature, timestamp, nonce)){  
  48.            out.print(echostr);  
  49.        }  
  50.   
  51.        out.close();  
  52.        out = null;          
  53.     }  
  54.   
  55.     /** 
  56.      * 處理微信服務器發來的消息  
  57.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  58.      */  
  59.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  60.         // TODO Auto-generated method stub  
  61.         // 消息的接收、處理、響應    
  62.     }  
  63.   
  64. }  

在doGet方法中調用了checkSignature方法,該方法尚未實現,咱們新建一個包 org.ivy.course.util 做爲一個工具包,並往該包中添加新類 SignUtil,添加類的方法是:包名右鍵 -->new --> class,填上類名,其它默認,完整代碼以下:
 
 
[java]  view plain copy
 
  1. package org.ivy.course.util;  
  2.   
  3. import java.security.MessageDigest;  
  4. import java.security.NoSuchAlgorithmException;  
  5. import java.util.Arrays;  
  6.   
  7. public class SignUtil {  
  8.     /** 
  9.      * 與接口配置信息中的 token 要一致,這裏賦予什麼值,在接口配置信息中的Token就要填寫什麼值, 
  10.      * 兩邊保持一致便可,建議用項目名稱、公司名稱縮寫等,我在這裏用的是項目名稱weixinface 
  11.      */  
  12.     private static String token = "weixinface";  
  13.       
  14.     /** 
  15.      * 驗證簽名 
  16.      * @param signature 
  17.      * @param timestamp 
  18.      * @param nonce 
  19.      * @return 
  20.      */  
  21.     public static boolean checkSignature(String signature, String timestamp, String nonce){  
  22.         String[] arr = new String[]{token, timestamp, nonce};  
  23.         // 將 token, timestamp, nonce 三個參數進行字典排序  
  24.         Arrays.sort(arr);  
  25.         StringBuilder content = new StringBuilder();  
  26.         for(int i = 0; i < arr.length; i++){  
  27.             content.append(arr[i]);  
  28.         }  
  29.         MessageDigest md = null;  
  30.         String tmpStr = null;  
  31.           
  32.         try {  
  33.             md = MessageDigest.getInstance("SHA-1");  
  34.             // 將三個參數字符串拼接成一個字符串進行 shal 加密  
  35.             byte[] digest = md.digest(content.toString().getBytes());  
  36.             tmpStr = byteToStr(digest);  
  37.         } catch (NoSuchAlgorithmException e) {  
  38.             // TODO Auto-generated catch block  
  39.             e.printStackTrace();  
  40.         }  
  41.         content = null;  
  42.         // 將sha1加密後的字符串可與signature對比,標識該請求來源於微信  
  43.         return tmpStr != null ? tmpStr.equals(signature.toUpperCase()): false;  
  44.     }  
  45.       
  46.     /** 
  47.      * 將字節數組轉換爲十六進制字符串 
  48.      * @param digest 
  49.      * @return 
  50.      */  
  51.     private static String byteToStr(byte[] digest) {  
  52.         // TODO Auto-generated method stub  
  53.         String strDigest = "";  
  54.         for(int i = 0; i < digest.length; i++){  
  55.             strDigest += byteToHexStr(digest[i]);  
  56.         }  
  57.         return strDigest;  
  58.     }  
  59.       
  60.     /** 
  61.      * 將字節轉換爲十六進制字符串 
  62.      * @param b 
  63.      * @return 
  64.      */  
  65.     private static String byteToHexStr(byte b) {  
  66.         // TODO Auto-generated method stub  
  67.         char[] Digit = {'0''1''2''3''4''5''6''7''8''9''A''B''C''D''E''F'};  
  68.         char[] tempArr = new char[2];  
  69.         tempArr[0] = Digit[(b >>> 4) & 0X0F];  
  70.         tempArr[1] = Digit[b & 0X0F];  
  71.           
  72.         String s = new String(tempArr);  
  73.         return s;  
  74.     }  
  75. }  

代碼添加完畢, 工程右鍵,刪除工程中的 ROOT.war 包,   而後工程右鍵 從新 打包一個 ROOT.war 包,名字必須和原來同樣,保存地址也和原來同樣,具體是,右鍵 -->  Export --> WAR file:
 
 
 
 
 
導出後,項目右鍵刷新工程,包 ROOT.war 就會從新出如今工程中,而後咱們提交咱們的工程到百度 BAE 上就好了,具體作法看下面。
 
 
五、提交修改後的代碼
 
    工程右鍵 --> Team --> 提交 --> ok, 如圖 18
 

                                        圖 18
 
     若是要驗證,就輸入你的百度帳號密碼,提交成功後,部署列表狀態欄會顯示「有新版」,此時點擊「快捷發佈」也等同上線。如圖 19 所示:
 
                                                                                                               圖 19

      發佈後,點擊查看,在彈出頁面的地址中添加上面叫你記住的那個  URL mappings ,若是你沒有改過,默認是「 /CoreServlet 」,若是你 實在忘了,能夠到 你的類 CoreServlet 中找到這個語句:   @WebServlet( "/CoreServlet" ),就是這個後綴,舉 個例子,例如你點擊查看的網站是   < http://weitest.duapp.com >  ,添加後綴後的地址是 < http://weitest.duapp.com   /CoreServlet > 填完網址後回車,就能看到以下頁面:
 
 
看到此畫面就說明你離成功只差一步了,記住複製此網頁的地址備用。
 
六、成爲微信開發者
 
    打開微信公衆平臺 -> 高級功能 -> 開發者模式,見圖 20:
                                                                        圖20
 
 
將咱們剛纔複製的地址黏貼到 URL ;
 
在填寫 Token 以前,也回到咱們的項目,在類 SignUtil 中有這麼一句代碼:
 
[java]  view plain copy
 
  1. private static String token = "weixinface";  
     代碼中的 token 的值咱們能夠隨意寫,可是,這裏是什麼值,在微信平臺上就要填寫對應的內容,全部,在 Token 那裏填上 weixinface,點擊「提交」,若是代碼沒有問題,瞬間你就能夠看到「你已成爲開發者」 的提示:如圖 22
 
                                                                              圖 22
 
       到此,全部的工做都已經完成,你能夠不斷豐富你的代碼,實現不一樣的功能。你也能夠在本身的微信中關注本身的訂閱號,只需掃描公衆平臺的二維碼就好了。
 
擴展說明:
     其實,上述提交代碼到百度 BAE 中的這麼一個操做,我以爲更多的是將 BAE 做爲一個穀倉,就是一個存放代碼的服務器來用,以方便咱們在任何地方均可以經過 SVN 工具檢出咱們的代碼,從而隨時開始咱們的項目,特別是多人一塊兒作的項目,而微信 Token 認證訪問的其實只有 ROOT.war 這個包,不信,你能夠另外安裝一個 SVN 工具,從新打包 ROOT.war,並經過 SVN 將 ROOT.war 這個包提交到 BAE 上,同樣能夠經過微信 Token 驗證,個人另一篇博客就是僅僅提交 ROOT.war 這個包的,有興趣的能夠去看看,可是,這是爲何?其實也很簡單,咱們打包的 ROOT.war 中其實已經有咱們的因此源代碼了,你能夠解壓 ROOT.war 文件,看看裏面到底有些什麼東西,你就會懂的。
相關文章
相關標籤/搜索