dyerac  
          dyerac In Java
          公告

          日歷
          <2006年8月>
          303112345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789
          統(tǒng)計
          • 隨筆 - 36
          • 文章 - 10
          • 評論 - 94
          • 引用 - 0

          導(dǎo)航

          常用鏈接

          留言簿(5)

          隨筆分類(49)

          隨筆檔案(36)

          文章分類(11)

          文章檔案(10)

          相冊

          dyerac

          搜索

          •  

          積分與排名

          • 積分 - 79505
          • 排名 - 705

          最新隨筆

          最新評論

          閱讀排行榜

          評論排行榜

           

          ??? 老早xc就在我耳邊絮絮叨叨gwt的好處呢,可是由于受google maps在我瀏覽器里總無法正常顯示的影響(莫非是人品問題?), 我差點(diǎn)就與它擦肩而過. 還是因?yàn)镃ain 某天在群里述說自己因?yàn)闆]有刪除gwt-user.jar中javax部分所受的痛苦折磨,才讓我決心一試gwt, 呵呵, 老大都出手了,小弟怎能落后呢?
          ??? 關(guān)于gwt的詳細(xì)內(nèi)容我就不多介紹了,具體可以參見我blog上轉(zhuǎn)載的兩篇文章Google Web Toolkit 入門gwt study .這里就主要結(jié)合我自己的試用經(jīng)歷講下吧.
          ??? ajax現(xiàn)在的應(yīng)用也很廣泛了,其中可能用的最多,也幾乎會在每本介紹ajax的書上出現(xiàn)的案例,大概就是關(guān)于用戶注冊時對用戶名的檢驗(yàn).因此我也選中用gwt完成類似的功能.考慮到demo的簡易性,具體的功能縮減如下:
          ????? 在輸入框中輸入用戶名后,將鼠標(biāo)點(diǎn)離輸入框, 程序?qū)⒄{(diào)用后臺servlet自動檢驗(yàn)輸入信息.如果輸入內(nèi)容為空,則提示錯誤信息;如果輸入信息為dyerac,則提示該用戶已注冊(本來應(yīng)該是先檢驗(yàn)數(shù)據(jù)庫看用戶名是否已經(jīng)存在,為了簡便我省去了這一步,直接用dyerac替代);如果都不是,則顯示出歡迎信息.
          ???? 同樣,你也可以直接點(diǎn)擊"test ajax"按鍵手工進(jìn)行檢驗(yàn),檢驗(yàn)原則和前面相同
          ????????
          ????? ajax demo

          ???? 好咯,下面就讓我們一步步來吧.
          ??? 1.下載gwt
          ?? 從 http://code.google.com/webtoolkit/ ?下載GWT的最新版本,將下載的壓縮文件解壓縮到D:/GWT目錄下。本書中的后續(xù)內(nèi)容中將使用%GWT_HOME%變量來引用這個目錄。點(diǎn)開目錄,會發(fā)現(xiàn)目錄中含有三個cmd文件和兩個jar文件:
          ??????????????
          ??? ?分別將他們加入classpath和path中
          ?
          ??? 2.創(chuàng)建工程:
          ??? 創(chuàng)建目錄%GWT_HOME%/gwt-workspace/gwtTrial, 通過命令行進(jìn)入到該目錄下,輸入命令projectCreator????? ?-eclipse gwtTrial? 創(chuàng)建eclipse同名工程. 然后用eclipse將該工程導(dǎo)入.
          ??? 在eclipse下給項(xiàng)目添加兩個包: com.dyerac.client,? com.dyerac.server.注意,gwt會把你的java代碼翻譯成js代碼,由于gwt的強(qiáng)制規(guī)定,所以需要翻譯的java代碼都必須放到以client結(jié)尾的包中,同時,為了程序的易讀性,gwt也建議把servlet放在server結(jié)尾的包中.

          ??? 3.代碼開發(fā)
          ??? gwt最方便的地方之一在于,你完全不用開發(fā)js代碼, gwt仿照awt開發(fā)了自己的一套組件庫,你可以通過這套組件庫像開發(fā)swing一樣開發(fā)自己的web頁面,然后調(diào)用gwt的工具將它翻譯成js代碼.
          ?? gwt另外一個好處在于在Ajax應(yīng)用中使用RPC消除了顯式地處理XMLHttpRequest和相關(guān)聯(lián)的服務(wù)器返回值的需要,因?yàn)镚WT對象會為你處理這些通訊工作。gwt采取了一種和老式ejb很像的方式來處理客戶端和服務(wù)端的異步通訊, 當(dāng)你開發(fā)一個需要被客戶端調(diào)用的服務(wù)時,你同時還需要開發(fā)兩個接口:

          package ?com.dyerac.client;
          import ?com.google.gwt.user.client.rpc.RemoteService;

          public ? interface ?InputService? extends ?RemoteService {
          ???
          public ?String?checkInput(String?req);
          }



          服務(wù)接口必須擴(kuò)展GWT接口RemoteService。它只定義了一個方法 checkInput(String req);

          你還需要定義一個接口,客戶端或最終被下載的JavaScript代碼將會用它調(diào)用服務(wù)方法。GWT使用了一種回調(diào)設(shè)計模式,當(dāng)我給出客戶端代碼的時候會再來描述它(請看MyInput.java)。

          package ?com.dyerac.client;

          import ?com.google.gwt.user.client.rpc.AsyncCallback;

          public ? interface ?InputServiceAsync {
          ????
          public ? void ?checkInput(String?req,?AsyncCallback?callable);
          }

          要使一個服務(wù)在GWT中可用必須遵守命名約定;在服務(wù)接口名(InputService)后增加Async后綴。AsyncCallback對象是GWT API的一部分,它的目的是為客戶端處理服務(wù)響應(yīng)。不管怎樣,等你看了這段代碼應(yīng)用的地方后會對這一行為有更清晰的了解。這些對象定義都位于用于生成客戶端JavaScript的Java代碼中。

          最后,你需要定義一個Java類來實(shí)現(xiàn)遠(yuǎn)程服務(wù)接口。這個類將會存在于你的Ajax應(yīng)用程序的服務(wù)器端。
          package?com.dyerac.server;

          import?com.dyerac.client.InputService;
          import?com.google.gwt.user.server.rpc.RemoteServiceServlet;

          public?class?InputServiceImpl?extends?RemoteServiceServlet?implements
          ????????InputService?
          {

          ????
          public?String?checkInput(String?req)?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????String?buf;
          ????????
          if?(req.equalsIgnoreCase("dyerac"))
          ????????????buf?
          =?"sorry,?this?id?has?been?registered";
          ????????
          else
          ????????????buf?
          =?"Hello,?"?+?req;
          ????????
          return?buf;
          ????}


          }

          該類必須擴(kuò)展RemoteServiceServlet,這是一個GWT API對象,它本身擴(kuò)展了javax.servlet.http.HttpServlet。也就是說,該類和它實(shí)現(xiàn)的接口需要被部署到你的servlet容器.(注: 在tomcat下部署的時候,需要刪除gwt-user.jar中的javax部分)

          現(xiàn)在,服務(wù)已經(jīng)定義完畢了,只剩下對應(yīng)頁面的java類沒有開發(fā):

          package?com.dyerac.client;

          import?com.google.gwt.core.client.EntryPoint;
          import?com.google.gwt.core.client.GWT;
          import?com.google.gwt.user.client.rpc.AsyncCallback;
          import?com.google.gwt.user.client.rpc.ServiceDefTarget;
          import?com.google.gwt.user.client.ui.Button;
          import?com.google.gwt.user.client.ui.ClickListener;
          import?com.google.gwt.user.client.ui.FocusListener;
          import?com.google.gwt.user.client.ui.Grid;
          import?com.google.gwt.user.client.ui.Label;
          import?com.google.gwt.user.client.ui.RootPanel;
          import?com.google.gwt.user.client.ui.TextBox;
          import?com.google.gwt.user.client.ui.Widget;

          public?class?MyInput?implements?EntryPoint,?ClickListener,?FocusListener?{

          ????Button?submit?
          =?new?Button("test?ajax");

          ????
          /**
          ?????*?輸入框
          ?????
          */

          ????TextBox?input?
          =?new?TextBox();

          ????
          /**
          ?????*?錯誤提示標(biāo)簽
          ?????
          */

          ????Label?message?
          =?new?Label();

          ????
          /**
          ?????*?一個Grid對象;實(shí)際上,是一個HTML?table
          ?????
          */

          ????Grid?grid?
          =?new?Grid(2,?2);

          ????
          /**
          ?????*?判斷是否是第一次得到焦點(diǎn).只有第一次得到焦點(diǎn)后,才會在失去焦點(diǎn)時進(jìn)行校驗(yàn)
          ?????
          */

          ????
          boolean?isFirstFocused?=?false;

          ????
          /*
          ?????*?當(dāng)瀏覽器載入應(yīng)用程序時本方法被調(diào)用。?本方法添加標(biāo)簽和文本框,以及一個?按鈕到頁面上,并為他們注冊監(jiān)聽器
          ?????
          */

          ????
          public?void?onModuleLoad()?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????grid.setWidget(0,?0,?input);
          ????????grid.setWidget(
          0,?1,?message);
          ????????grid.setWidget(
          1,?0,?submit);
          ????????
          //?添加點(diǎn)擊監(jiān)聽器
          ????????submit.addClickListener(this);
          ????????
          //?添加得失焦點(diǎn)監(jiān)聽器
          ????????input.addFocusListener(this);
          ????????RootPanel.get().add(grid);
          ????}


          ????
          public?void?onClick(Widget?sender)?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????check();
          ????}


          ????
          /**
          ?????*?校驗(yàn)輸入框中內(nèi)容,只有內(nèi)容非空且不為dyerac時,?才會顯示正確歡迎信息
          ?????
          */

          ????
          public?void?check()?{
          ????????
          //?為服務(wù)器端服務(wù)創(chuàng)建一個客戶端存根的實(shí)例
          ????????InputServiceAsync?inputService?=?(InputServiceAsync)?GWT
          ????????????????.create(InputService.
          class);
          ????????ServiceDefTarget?target?
          =?(ServiceDefTarget)?inputService;
          ????????
          //?下面的"/inputservice"表示之前開發(fā)的InputServiceImpl在web應(yīng)用中對應(yīng)的servlet映射
          ????????
          //?即web.xml配置的內(nèi)容.
          ????????
          //?在開發(fā)中,也可以在MyInput.gwt.xml中進(jìn)行配置
          ????????target.setServiceEntryPoint("/inputservice");

          ????????AsyncCallback?callback?
          =?new?AsyncCallback()?{
          ????????????
          public?void?onSuccess(Object?result)?{
          ????????????????String?s?
          =?(String)?result;
          ????????????????
          if?(s.startsWith("H"))?{
          ????????????????????
          if?(message.getStyleName().equalsIgnoreCase("warning"))
          ????????????????????????message.removeStyleName(
          "WARNING");
          ????????????????????message.setText(s);
          ????????????????}
          ?else?{
          ????????????????????message.setStyleName(
          "WARNING");
          ????????????????????message.setText(s);
          ????????????????}

          ????????????}


          ????????????
          public?void?onFailure(Throwable?caught)?{
          ????????????????message.setStyleName(
          "WARNING");
          ????????????????message.setText(
          "found?a?error:?"?+?caught.toString());
          ????????????}

          ????????}
          ;
          ????????String?tmp?
          =?input.getText();
          ????????
          //?先檢驗(yàn)輸入是否為空
          ????????if?(tmp.length()?<?1)?{
          ????????????message.setStyleName(
          "WARNING");
          ????????????message.setText(
          "A?textbox?had?invalid?content?such?"
          ????????????????????
          +?"as?a?blank?entry.");
          ????????}
          ?else?{
          ????????????
          //?調(diào)用服務(wù)器端方法
          ????????????inputService.checkInput(tmp,?callback);
          ????????}

          ????}


          ????
          public?void?onFocus(Widget?sender)?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????if?(isFirstFocused?==?false)
          ????????????isFirstFocused?
          =?true;
          ????????message.setText(
          "");
          ????}


          ????
          public?void?onLostFocus(Widget?sender)?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????if?(isFirstFocused?==?true)?{
          ????????????check();
          ????????}

          ????}

          }

          ?

          怎么樣,是不是像開發(fā)swing一樣簡單? 再說明一下,本類中的onModuleLoad()方法就如同普通java類中的main方法,是整個程序的切入口.

          代碼開發(fā)完后,就要調(diào)用gwt工具進(jìn)行編譯(把java代碼翻譯成js代碼),這里,只有MyInput.java是針對頁面開發(fā)的,所以我們只需要翻譯它.還是在命令行下進(jìn)入%GWT_HOME%/gwt-workspace/gwtTrial, 輸入命令applicationCreator -eclipse gwtTrial -ignore com.dyerac.client.MyInput (-ignore表示該類已存在,不需要重新創(chuàng)建)
          隨后刷新eclipse下的工程,發(fā)現(xiàn)結(jié)構(gòu)如下:
          注:下圖中DialogBoxExample有關(guān)的內(nèi)容是我另外開發(fā)


          ??? MyInput-shell.cmd是在宿主模式(Hosted Mode)下啟動程序,宿主模式是指我們和沒有轉(zhuǎn)換為Ajax應(yīng)用的GWT應(yīng)用交互的狀態(tài)。當(dāng)我們開發(fā)和調(diào)試時,我們就一直處在宿主模式下。在這種情況下,Java虛擬機(jī)使用GWT內(nèi)置的瀏覽器運(yùn)行GWT應(yīng)用編譯后的class內(nèi)容,因此能夠提供"編碼、測試、調(diào)試"過程的最佳速度。

          ??? 對應(yīng)的還有Web模式,是指已經(jīng)成功轉(zhuǎn)化為Ajax應(yīng)用的狀態(tài),這種狀態(tài)下,我們已經(jīng)開始通過Web方式來訪問Ajax應(yīng)用了。在Web模式下運(yùn)行時,不再需要GWT工具包或者JVM的支持。啟動web模式需要用MyInput-compile.cmd先編譯整個應(yīng)用.
          ?
          ?? 另外,我們還需要修改一下MyInput.gwt.xml:
          ?? 添加<servlet path="/inputservice" class="com.dyerac.server.InputServiceImpl" />

          <module>

          ????
          <!--?Inherit?the?core?Web?Toolkit?stuff.??????????????????-->
          ????
          <inherits?name='com.google.gwt.user.User'/>

          ????
          <!--?Specify?the?app?entry?point?class.???????????????????-->
          ????
          <entry-point?class='com.dyerac.client.MyInput'/>
          ????
          ????
          <servlet?path="/inputservice"?class="com.dyerac.server.InputServiceImpl"?/>?
          </module>

          最后,為了調(diào)試方便,我們可以直接點(diǎn)擊MyInput-shell.cmd,在宿主模式下運(yùn)行程序

          ajax demo


          4.一些困惑:?
          ?? 雖然gwt很是方便,但我覺得它自身就是一個完整的體系了,因此如何與現(xiàn)有框架進(jìn)行整合還是個問題.比如,如何與jsf整合呢?還望各位高手支招
          ?? 而且gwt還是缺乏一款強(qiáng)大的ide支持,如果實(shí)現(xiàn)頁面的wysiwyg就方便多了.另外由命令行編譯也不是很方便
          呵呵,期待gwt下一個版本^
          ?????

          ?

          posted on 2006-07-29 14:49 dyerac in java... 閱讀(2449) 評論(10)  編輯  收藏 所屬分類: ajax原創(chuàng)文章
          評論:
           
          Copyright © dyerac in java... Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 桐柏县| 依安县| 天祝| 六枝特区| 环江| 九寨沟县| 高唐县| 义马市| 八宿县| 河西区| 长治县| 南安市| 雷州市| 礼泉县| 贵州省| 丹凤县| 久治县| 山阳县| 双峰县| 江山市| 昆山市| 星座| 米泉市| 米林县| 龙泉市| 克拉玛依市| 宁河县| 西平县| 彰化县| 颍上县| 民勤县| 江永县| 牟定县| 庆元县| 利津县| 红安县| 桂东县| 斗六市| 克拉玛依市| 秦皇岛市| 文成县|