(轉)微信公眾平台開發之基於百度 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 也可以搭建一個開發環境,具體操作,請看另外一篇博客。
 
步驟:
 
1、去BAE快速創建一個JAVA應用
    去到百度開放雲首頁 ( http://developer.baidu.com/ ),點擊右上角 “管理控制台” ,進入我的應用頁面:如圖 1

                                        圖 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:
 
[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 上就行了,具體做法看下面。
 
 
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 中有這么一句代碼:
 
[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 文件,看看里面到底有些什么東西,你就會懂的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM