這部分將實際開發一個應用,套用了一個老外的樣本模板,做了一個線上禮品的簡易版本。
先講一下應用的結構
頁面端:
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的開發。
資源
1、樣本來源程式:下載
2、dwr主站:http://getahead.ltd.uk/dwr
3、ajax主站:http://en.wikipedia.org/wiki/AJAX