ajax/dwr/struts實例開發

2005是Ajax最火爆的年份,以gmail爲先驅的Ajax應用已經逐漸深入人心了。也許這就是所謂的輪迴吧,計算機界面的設計從最初瘦到胖再到瘦,如今又要開始胖了。不過,在web界面的胖與之前的胖還是有很多區別的,web界面的胖主要依賴於DHML和Javascript來實現。這也是本文的來由了,相信很多OO的開發人員都不願與頁面層的效果打交道,尤其是Javascript的這樣的開發語言,我也是其中之一了,非常不喜歡Javascript,語法鬆散,結構複雜。反正是不喜歡了,但是在web時代,既然流行胖子,想不用Javascript是不可能的了,那麼怎麼樣來簡化Ajax的開發呢?DWR由此延生了,他封裝了XMLHttpRequest,直接調用服務端的方法,省了好多Javascript啊^_^
Struts雖然已經開始開下陡路,但底子厚,將DWR與Struts結合依然會是大多數開發者的選擇。
本文分兩部分:框架介紹和實例開發。先來:

第一部分 框架介紹

一、Ajax介紹
Ajax--Asynchronous JavaScript and XML,異步JavaScript和XML。
名字中已經包含Ajax的組成部分:異步處理XMLHttpRequest,JavaScript,XML。
其中:
1、XMLHttpRequest是Ajax的關鍵部分,正是由於他的存在,才使得胖子越來越吃香了。
2、JavaScript是Ajax的必備部分,沒有他還玩個屁
3、XML是Ajax數據格式的推薦方式,但也可以不用
當然還少不了CSS,有了CSS使得在Ajax中更容易修改用戶的界面
Ajax的細節和樣例使用就不多說了,N多的資源,自己找吧。

二、DWR介紹
DWR-Direct Web Remote,翻譯過來應該是直接遠程網頁訪問。(這個Web一直找不到好的詞語來表達,這裏就用網頁吧)
如名字所述,DWR的主要特點就是可以在Ajax中直接調用服務器上的方法,很奇妙吧。就是說,不需要通過URL來告訴服務來處理,而是直接在Javascript中調用類的方法,並返回數據。
DWR簡化了Ajax的開發:
1、封裝了Ajax中的使用,不再需要直接使用XMLHttpRequest了,這可是非常重要的,減少了好多Javascript呀
2、通過回調函數的方式,簡化了錯誤處理及返回數據的處理。
3、直接調用服務器類的方法,不再需要通過URL方式,也省了不少的事。

DWR的主要部件有:dwr.xml/engine.js/util.js,前者是DWR的Servlet使用的配置文件,後兩者DWR替我們封裝的Ajax的代碼,當然也提供了其他有用的功能。

三、Struts介紹
Struts還用介紹嗎?沒聽說過?那就不用往下看,休息休息吧^_^
這裏就說一下在DWR如何調用Struts中Action的方法吧,說白了,是不可能的。這不是白說嗎#$@$@%@#
實際上是這樣的,雖然DWR支持方法的調用,但ActionForward/ActionForm/ActionMap這些東西如何在DWR調用方法前生成呢?我也不知道,所以DWR對Struts的支持實際上就是要重構Action中的方法,去掉上面的東西,然後就可以了(這是DWR說的,可不是我說的^_^)。

這部分將實際開發一個應用,套用了一個老外的示例模板,做了一個在線禮品的簡易版本。
先講一下應用的結構
頁面端:
    demo.jsp用來展示界面
服務端:
    DemoAction是Struts中的Action子類負責控制轉換,
    DemoFacade是業務類負責業務處理。
    Goods是一個業務實體類

Struts部分的配置就忽略不說了,實際上這個應用並沒有包含Struts的配置
主要講一下dwr的配置,首先需要在web.xml增加下面的servelt映射:

xml 代碼
  1. <servlet>  
  2.     <description>Direct Web Remoter Servlet</description>  
  3.     <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>  
  4.   </servlet>  
  5.   <servlet-mapping>  
  6.     <servlet-name>dwr-invoker</servlet-name>  
  7.     <url-pattern>/dwr/*</url-pattern>  
  8.   </servlet-mapping>  

 

如上uk.ltd.getahead.dwr.DWRServlet是dwr的核心,用來處理javascript的對遠程方法的調用,還有其他參數請參考相關文檔。
然後,需要在dwr.xml配置相應的遠程方法(與具體需要在客戶端調用的方法相關),如下爲演示應用的配置:

xml 代碼
  1. <dwr>  
  2.     <allow>  
  3.         <convert converter="bean" match="dwr.demo.Goods"/>  
  4.         <create creator="new" javascript="DemoAction" class="dwr.demo.DemoAction">  
  5.             <include method="query4dwr"/>  
  6.             <include method="copy4dwr"/>  
  7.             <include method="paste4dwr"/>  
  8.         </create>  
  9.         <create creator="new" javascript="DemoFacade" class="dwr.demo.DemoFacade">  
  10.             <include method="queryList"/>  
  11.             <include method="restore"/>  
  12.             <include method="del"/>  
  13.         </create>  
  14.       </allow>  
  15. </dwr>  

如上有一個轉換器(converter)是用來映射dwr.demo.Goods爲bean類型,其他轉換器類型請參考相關文檔;還有兩個創建器分別創建 javascript中的DemoAction類和DemoFacade類,分別對應dwr.demo.DemoAction類和 dwr.demo.DemoFacade,其中定義的方法就可以從javascript中直接調用了。
最後,我們需要在頁面中包含相應的javascript:
  <script src="http://www.zhmy.com/dwr/interface/DemoAction.js"></script>
  <script src="http://www.zhmy.com/dwr/interface/DemoFacade.js"></script>
  <script src="http://www.zhmy.com/dwr/engine.js"></script>
  <script src="http://www.zhmy.com/dwr/util.js"></script>
如上,dwr/interface/DemoAction.js和dwr/interface/DemoFacade.js是dwr自動生成的 javascript文件,包含相應的類及方法,dwr/engine.js是dwr的核心引擎腳本處理客戶端調用的轉換,dwr/util.js包含了工具函數簡化頁面處理。

下面以查詢爲例,看一下dwr的具體使用:
DemoAction:
    public List query4dwr(int type, boolean needClear, HttpServletRequest request) {
        if (needClear) request.getSession().removeAttribute("dwr.demo.goodsId");
        return demoFacade.queryList(type);
    }
demo.jsp:
  function updateResults() {
    DWRUtil.removeAllRows("goodsbody");
    var type = document.getElementById("type").value;
    DemoAction.query4dwr(type, true, fillTable);
  }
  function fillTable(goods) {
    document.forms[0].select.checked = false;
    document.getElementById("totalRecords").innerHTML = goods.length;
    DWRUtil.addRows("goodsbody", goods, [ addCheckbox, getName, getPrice, getCount]);
  }
如上,DemoAction.query4dwr(type, true, fillTable)就可以直接調用DemoAction的方法了,這裏fillTable是函數,dwr通過回調函數的方式來進行後續處理。比較一下 javascript和action中的方法參數,HttpServletRequest是可以不傳的,dwr會自動加上,另一個就是回調參數放在最後,這是比較好的方式,其他方式請參考文檔。

最後看一下,dwr如何與Struts集成,如下代碼:
    public ActionForward query(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String type = request.getParameter("type");
        //或者從form中取值
        
        List goodsList = query4dwr(Integer.parseInt(type), true, request);
        request.setAttribute("goodsList", goodsList);
        
        return mapping.findForward("success");
    }

    public List query4dwr(int type, boolean needClear, HttpServletRequest request) {
        if (needClear) request.getSession().removeAttribute("dwr.demo.goodsId");
        return demoFacade.queryList(type);
    }
前一個方法是Struts的方式,但dwr不支持,因此要重構一下在下面的方法纔可以被dwr調用。
實際上,只有在方法中需要使用到HttpServletRequest是才需要重構方法,如果不使用HttpServletRequest,我們就可以直接調用業務層的類的方法,這樣即簡單又方便,如下:
demo.jsp:
  function restore() {
    DemoFacade.restore(updateResults);
  }

DemoAction:
    public synchronized void restore() {
        goodsList.clear();    
        initGoods();
    }

小結

  dwr封裝了ajax中與服務端交互的模塊,通過直接調用服務端類的方法簡化了客戶端與服務端的交互。雖然說還缺省類似tag這樣的組件,但已經很大程度簡化了ajax的開發。

 

資源
  1、示例源程序:下載
  2、dwr主站:http://getahead.ltd.uk/dwr
  3、ajax主站:http://en.wikipedia.org/wiki/AJAX

 
發佈了83 篇原創文章 · 獲贊 0 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章