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部分的配置就
  先講一下應用的結構
  頁面端:
  demo.jsp用來展示介面
  服務端:
  DemoAction是Struts中的Action子類負責控制轉換,
  DemoFacade是業務類負責業務處理。
  Goods是一個業務實體類
  
  Struts部分的配置就忽略不說了,實際上這個應用並沒有包含Struts的配置
  主要講一下dwr的配置,首先需要在web.xml增加下面的servelt映射:
<servlet>
      
  <description>Direct Web Remoter Servlet</description>
      
  <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
    
  </servlet>
    
  <servlet-mapping>
      
  <servlet-name>dwr-invoker</servlet-name>
      
  <url-pattern>/dwr/*</url-pattern>
    
</servlet-mapping>
如上uk.ltd.getahead.dwr.DWRServlet是dwr的核心,用來處理javascript的對遠端方法的調用,還有其他參數請參考相關文檔。
  然後,需要在dwr.xml配置相應的遠端方法(與具體需要在用戶端調用的方法相關),如下為演示應用的配置:
<dwr>
      
  <allow>
          
  <convert converter="bean" match="dwr.demo.Goods"/>
          
  <create creator="new" javascript="DemoAction" class="dwr.demo.DemoAction">
              
  <include method="query4dwr"/>
              
  <include method="copy4dwr"/>
              
  <include method="paste4dwr"/>
          
  </create>
          
  <create creator="new" javascript="DemoFacade" class="dwr.demo.DemoFacade">
              
  <include method="queryList"/>
              
  <include method="restore"/>
              
  <include method="del"/>
          
  </create>
        
  </allow>
</dwr>
  
    
      
        
          
          
          
              
                 
                 
                 
          
      
    
               
  如 上有一個轉換器(converter)是用來映射dwr.demo.Goods為bean類型,其他轉換器類型請參考相關文檔;還有兩個創建器分別創建 javascript中的DemoAction類和DemoFacade類,分別對應dwr.demo.DemoAction類和 dwr.demo.DemoFacade,其中定義的方法就可以從javascript中直接調用了。 
最後,我們需要在頁面中包含相應的javascript:
  
  
  
  
 <script src='dwr/interface/DemoAction.js'></script>
    
  <script src='dwr/interface/DemoFacade.js'></script>
    
  <script src='dwr/engine.js'></script>
    
<script src='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的开发。 
 
沒有留言:
發佈留言