http://getahead.ltd.uk/dwr/ 1、DWR: Easy AJAX for JAVA 作為一個(gè)java open source library,DWR可以幫助開發(fā)人員完成應(yīng)用AJAX技術(shù)的web程序。它可以讓瀏覽器上的javascript方法調(diào)用運(yùn)行在web服務(wù)器上java方法。 DWR主要由兩部門組成。javascript與web服務(wù)器通信并更新web頁(yè);運(yùn)行在web服務(wù)器的Servlet處理請(qǐng)求并把響應(yīng)發(fā)回瀏覽器。 DWR采用新穎的方法實(shí)現(xiàn)了AJAX(本來(lái)也沒有確切的定義),在java代碼基礎(chǔ)上動(dòng)態(tài)的生成javascript代碼。web開發(fā)者可以直接調(diào)用這些javascript代碼,然而真正的代碼是運(yùn)行在web服務(wù)器上的java code。出與安全考慮,開發(fā)者必須配置哪些java class暴露給DWR.(dwr.xml) 這種從(java到j(luò)avascript)調(diào)用機(jī)制給用戶一種感覺,好象常規(guī)的RPC機(jī)制,或RMI or SOAP.但是它運(yùn)行在web上,不需要任何瀏覽器插件。 DWR不認(rèn)為瀏覽器和web服務(wù)器之間協(xié)議重要,把系統(tǒng)界面放在首位。最大挑戰(zhàn)是java method call的同步特征與ajax異步特性之間的矛盾。在異步模型里,結(jié)果只有在方法結(jié)束后才有效。DWR解決了這個(gè)問(wèn)題,把回調(diào)函數(shù)當(dāng)成參數(shù)傳給方法,處理完成后,自動(dòng)調(diào)用回調(diào)方法。 這個(gè)圖表顯示了,通過(guò)javascript事件,DWR能改變select的內(nèi)容,當(dāng)然這些內(nèi)容由java代碼返回。 javascript函數(shù)Data.getOptions(populateList)由DWR動(dòng)態(tài)生成,這個(gè)函數(shù)會(huì)調(diào)用java class Data類的方法。DWR處理如何遠(yuǎn)程調(diào)用,包括轉(zhuǎn)換所有的參數(shù)和返回的結(jié)果(javascript\java)。java方法執(zhí)行完后,執(zhí)行回調(diào)方法populateList。在整個(gè)過(guò)程中我們就想在用本地的方法一樣。 2、Getting Started 廢話少說(shuō),試試就ok了。 <?xml version="1.0" encoding="ISO-8859-1"?> <web-app id="dwr"> dwr.xml 與web.xml同目錄 index.html dwr.jar 下載放lib下 完了,什么,夠了,就這些。訪問(wèn)ok! 通過(guò)研究uk.ltd.getahead.dwr.DWRServlet這個(gè)servlet來(lái)研究下dwr到底是如何工作滴。
代碼 web.xml配置 這樣所有的/dwr/*所有請(qǐng)求都由這個(gè)servlet來(lái)處理,它到底處理了些什么能。我們還以上面最簡(jiǎn)單的例子來(lái)看。 1、 web服務(wù)器啟動(dòng),DWRServlet init()方法調(diào)用,init主要做了以下工作。 設(shè)置日志級(jí)別、實(shí)例化DWR用到的單例類(這些類在jvm中只有一個(gè)實(shí)例對(duì)象)、讀去配置文件(包括dwr.jar包中的dwr.xml,WEB-INF/dwr.xml. config*.xml)。 2、請(qǐng)求處理 DWRServlet.doGet, doPost方法都調(diào)用processor.handle(req, resp)方法處理。Processor對(duì)象在init()方法中已經(jīng)初始化了。 代碼 public void handle(HttpServletRequest req, HttpServletResponse resp) 哦。這些恍然大悟。dwr/*處理的請(qǐng)求也就這幾種。 (1)dwr/index.html,dwr/test/這種只能在debug模式下使用,調(diào)試用。 dwr/engine.js,dwr/util.js,dwr/deprecated.js當(dāng)這個(gè)請(qǐng)求到達(dá),從dwr.jar包中讀取文件流,響應(yīng)回去。(重復(fù)請(qǐng)求有緩存) (2)當(dāng)dwr/interface/這種請(qǐng)求到來(lái),(例如我們?cè)趇ndex.html中的 <script type=‘text/javascript‘ src=‘dwr/interface/JDate.js‘></script>)DWR做一件偉大的事。把我們?cè)赪EB-INF/dwr.xml中的 <create creator="new" javascript="JDate"> <param name="class" value="java.util.Date"/> </create> java.util.Date轉(zhuǎn)化為javascript函數(shù)。 http://localhost:port/simpledwr/dwr/interface/JDate.js看看吧。 細(xì)節(jié)也比較簡(jiǎn)單,通過(guò)java反射,把方法都寫成javascript特定的方法。(我覺得這些轉(zhuǎn)換可以放到緩存里,下次調(diào)用沒必要再生成一遍,不知道作者為什么沒這樣做)。 (3)dwr/exec javascript調(diào)用方法時(shí)發(fā)送這種請(qǐng)求,可能是XMLHttpRequest或IFrame發(fā)送。 當(dāng)然,javascript調(diào)用的方法簽名與java代碼一致,包括參數(shù),還有javascript的回調(diào)方法也傳到了服務(wù)器端,在服務(wù)器端很容易實(shí)現(xiàn)?;卣{(diào)方法的java的執(zhí)行結(jié)果 返回類似 <script>callMethod(結(jié)果)<script>的javascript字符串,在瀏覽器執(zhí)行。哈,一切就這么簡(jiǎn)單,巧妙。
dwr的設(shè)計(jì)構(gòu)思很是巧妙。 |
simpledwr.rar | ||
描述: | 最簡(jiǎn)單的一個(gè)例子. | ![]() 下載 |
文件名: | simpledwr.rar | |
文件大小: | 137 KB | |
下載過(guò)的: | 文件被下載或查看 479 次 |
howitworks.png | |
描述: | |
文件大小: | 31 KB |
看過(guò)的: | 文件被下載或查看 422 次 |
1、最小配置
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<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>
servlet中加
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>logLevel</param-name>
<param-value>DEBUG</param-value>
</init-param>
我是喜歡用log4j輸出日志,那么在log4j.properties下加,log4j.logger.uk.ltd.getahead.dwr = debug。這樣可以看DWR的調(diào)試日志。
4、多dwr.xml文件的配置
可能有幾種情況,我們一一列舉。 一個(gè)servlet,多個(gè)dwr.xml配置文件;多個(gè)servlet,每個(gè)servlet對(duì)應(yīng)一個(gè)或多個(gè)dwr.xml.
一個(gè)servlet,多個(gè)dwr.xml配置文件;
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>config-1</param-name>
<param-value>WEB-INF/dwr1.xml</param-value>
</init-param>
<init-param>
<param-name>config-2</param-name>
<param-value>WEB-INF/dwr2.xml</param-value>
</init-param>
</servlet>
多個(gè)servlet,每個(gè)servlet對(duì)應(yīng)一個(gè)或多個(gè)dwr.xml
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<!--用classes/dwr.xml-->
</servlet>
<servlet>
<servlet-name>dwr-invoker1</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>config-admin</param-name>
<param-value>WEB-INF/dwr1.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dwr-invoker1</servlet-name>
<url-pattern>/dwr1/*</url-pattern>
</servlet-mapping>
1、java的方法避免用 java 和 javascript的關(guān)鍵字。 如 try()方法 或 delete()方法。
2、在你的java類中不要出現(xiàn)重載 avoid overloaded methods.
3、在生產(chǎn)環(huán)境下,你可以把deprecated.js engine.js util.js 合并成一個(gè),并放到web容器內(nèi),直接在htm,jsp中引用。 (對(duì)于java代碼轉(zhuǎn)換成的javascript代碼也可以這么做,免得每次生成javascript代碼浪費(fèi)時(shí)間)
4、研究一下Bean Converters。POJOjava對(duì)象必須嚴(yán)格按照 getProperty() setProperty()定義。Bean Converters是按照 java對(duì)象的 get set方法工作的。DWR1.1加了Object Converters,是按private int property;這類屬性工作的。
<convert converter="bean" match="example.Fred"/>
<param name="exclude" value="property1, property2"/>
</convert>
當(dāng)你這樣配置時(shí),java對(duì)象轉(zhuǎn)化成的javascript對(duì)象不包括property1和property2。
<convert converter="bean" match="example.Fred"/>
<param name="include" value="property1, property2"/>
</convert>
反過(guò)來(lái)java對(duì)象轉(zhuǎn)化成的javascript對(duì)象直包括property1和property2。
5、<convert converter="collection" match="java.util.Collection"/>
<convert converter="map" match="java.util.Map"/>
這也是容易出問(wèn)題的地方.
如
package example;
public class Person{
private String name;
get ... set
private List relationPerson;
public List setRelationPerson(List relationPerson){
this.relationPerson=relationPerson;
}
} <convert converter="bean" match="example.Person"/>
</convert>
<signatures>
<![CDATA[
import java.util.Set;
import example.Person;Person.setRelationPerson(List<Person>);
]]>
</signatures>在jdk1.5泛型中有寫法區(qū)別
6、另外在Set,List等做為方法參數(shù)時(shí)也會(huì)出現(xiàn)混淆。返回集合類型不會(huì)出現(xiàn)問(wèn)題,想想就知道了。
如 在Test類中有 public Set testBeanSetParam(Set test) 這個(gè)方法,客戶端得到的javascript方法可能是Test.testBeanSetParam(p0,callback);當(dāng)我們javascript調(diào)用這個(gè)方法時(shí),鬼才知道怎么確定p0的類型,也不可能知道Set集合中該放什么類型的java對(duì)象,所以dwr的 special signatures syntax 確定這些集合和內(nèi)容的類型
<signatures>
<![CDATA[
import java.util.Set;
import example.Test;Test.testBeanSetParam(Set<TestBean>);
<!--Test.stringStringMapParam(Map<String, String>);-->
]]>
</signatures>
7、Creators
<allow>
<create creator="..." javascript="..." scope="...">
<param name="..." value="..."/>
<auth method="..." role="..."/>
<exclude method="..."/>
<include method="..."/>
</create>
...
</allow>
為了更少的暴露業(yè)務(wù)方法,最好配置include屬性。
dwr支持new ,script,struts....幾種集成方法,也支持static方法的調(diào)用,我覺得最好的是spring,其他感覺是處理遺留問(wèn)題處理。
8、engine_js 作為dwr框架客戶端核心,主要完成xmlHttp或iframe的構(gòu)造,我們沒必要關(guān)心它如何實(shí)現(xiàn)。有幾點(diǎn)創(chuàng)新的我們可以學(xué)習(xí)下。
Call Batching 我們可以把幾個(gè)客戶端請(qǐng)求一起放送到服務(wù)器端,減少了網(wǎng)絡(luò)交互,但要注意依存關(guān)系和他們處理的順序。
Call Ordering 同步異步調(diào)整。一般用默認(rèn)的就好了。注意依存關(guān)系。
Remoting Hooks 鉤子,"small AOP"
依存關(guān)系解釋。 如果 request1() request2()兩個(gè)業(yè)務(wù)邏輯方法,request2方法需要用到request1方法從服務(wù)器端返回的結(jié)果。如果調(diào)用request2時(shí),request1還沒處理或還沒請(qǐng)求。 下拉框連動(dòng)可能有這個(gè)問(wèn)題。
9、util.js propotype.js有些重復(fù),這讓我很難受。只能改代碼了,可別壞了開元協(xié)議。
10、如果你的回調(diào)方法想加其他參數(shù)
var dataFromBrowser = ...;
var callbackProxy = function(dataFromServer) {
callbackFunc(dataFromServer, dataFromBrowser);
};
var callMetaData = { callback:callbackProxy };
Remote.method(params, callMetaData);
11、dwr1.1
1.1只能算一個(gè)bug消除版本,沒有什么大的功能調(diào)整。源代碼結(jié)構(gòu)做了些調(diào)整。2.0有新的特征加入。It has a far broader scope; the major new features are accessibility enhancements, and what now appears to
be called ‘Comet‘. 在文檔中提到了“Comet”,估計(jì)與DWR2.0作者想法類似。Chinese
Yenwen Feng spoke at JavaTwo in Taiwan in Chinese. He has provided his Powerpoint slides and the
examples that go with them as downloads:
- Powerpoint presentation [.ppt] [.rar]
- Mini-site created from presentation
- Examples archive [.rar]
Fran?ais / French
Julien Dubois vient d‘écrire un livre en Fran?ais sur Spring, lequel inclut un chapitre sur DWR.
La bonne nouvelle est que ce chapitre fait partie de ceux téléchargeables gratuitement.
Téléchargez le PDF. Spring par la pratique est disponible maintenant.Laurent Bois a écrit un article intitulé des "DWR sait rendre Ajax simple". Il commence
"Aujourd’hui les technologies de base fournies par les navigateurs web, c’est à dire afficher
le contenu de documents, ont été poussées jusqu’aux limites."Julien Dubois has recently written a French book primarily about Spring - it includes a section
on DWR. The great news is that this chapter is one of the free download chapters.
Get the PDF. Spring par la Practique is available now.Laurent Bois has written an article entitled "DWR makes Ajax simple". It begins: "Today the
basic technologies provided by web browsers were pushed until the limits".Italiano / Italian
Federico Paparoni ha tradotto la lezione privata di Java.net in Italiano. è disponibile qui:
"Sviluppare Applicazioni AJAX in Java".Federico Paparoni translated the Java.net tutorial into Italian. It is available here:
"Sviluppare Applicazioni AJAX in Java".Português / Portuguese
Pedro Pimentel escreveu um tutorial PDF em português de como iniciar no DWR. Come?a assim:
"Este tutorial assume que você tenha um conhecimento básico de aplica??es web em java. Entretanto,
conhecimento em C garante um bom entendimento dos códigos".Pedro Pimentel has written a PDF tutorial on how to get started with DWR in Portuguese. It begins:
"This tutorial assumes you have basic knowledge of web applications in Java. However some ‘C‘
knowledge will get you started."Non-English Documentation submitted by joe on 22 Aug 2006 - 19:41
聯(lián)系客服