当前位置:文档之家› DWR 学习总结

DWR 学习总结

DWR 学习总结
DWR 学习总结

DWR基础

DWR(Direct Web Remoting)是一个WEB远程调用框架

利用DWR可以在客户端利用JavaScript直接调用服务端的Java方法并返回值给JavaScript就好像直接本地客户端调用一样(DWR根据Java类来动态生成JavaScrip代码).它的最新版本DWR0.6添加许多特性如:支持Dom Trees的自动配置,支持Spring(JavaScript远程调用spring bean),更好浏览器支持,还支持一个可选的commons-logging日记操作.

creator在dwr中主要的职责就是把用户发布在dwr.xml中的class进行实例化,

converter的职责是在接受请求时把客户端的javascript对象转换成服务器端的java对象,通过调用发布的java bean后,在把返回的java的对象转化成javascript的对象给客户端调用

dwr.xml有两个主要的元素:init,arrow

init是用来定义你可以使用的converter和creator它们都有一个id和class的属性:id是一个标志可以在arrow元素中被引用于配置create和convert的,class是具体的类,的其定义样式如下:

arrow是用于定义你允许dwr创建和转换的java bean,包含两种类型:create和convert。其标签样式如下:

create就是配置哪些类是可以由dwr创建的,其包含creator,javascript,creator也是通过init元素进行定义的,creator还有一个javascript的属性,其定义的值就是在javascript中对应的对象名称

convert就是配置哪些java bean是可以通过dwr转换的,其包含converter,match属性,coverter就是选择转换的converter由init中配置,match就是可以转换的java bean

dwr已经为你提供了大量的creator和converter如:jsf,none,new,pageflow,spring,script,struts这几种creator,和null,enum,primitive,bignumber,string,array,map,collection,date,dom,dom4j,jdom,xom,servlet,bean,object,hibernate这几种convertor

如果你觉得dwr提供的creator和converter还不能满足你的需求时还可以定制自己的creator 和converter把它们部署到dwr.xml中,并把要发布的bean和method放到creators中,

如果你使用dwr的测试页面,你还可以得到一个以你配置的js文件,js文件对你配置的creator 和method进行了映射,其中的planApp是你发布的scriptName,get是发布调用的class方法,p0是方法传入的参数,callback是处理判断成功的标志。

planApp.get = function(p0, callback) {

DWREngine._execute(planApp._path, 'planApp', 'get', p0, callback);

}

现在我们看看dwr在页面上怎样跟服务器交互,dwr为我们提供了一个叫engine.js文件中定义一个DWREngine的javascript对象,其主要功能是处理页面和servlet之间的数据传递和转换。当中有三个函数需要特别的留意

1、_execute由界面的javascript调用根据传入的参数进行一系列的初始化,并调用调用endBatch调用_sendData与服务器的servlet进行交互

其传入的参数主要有

path——在/WEB-INF/web.xml配置的url-pattern,

scriptName——/WEB-INF/dwr.xml中creator的javascript的名称,methodName——creator的方法名,

vararg_params——传进的值和一些控制参数

2、_sendData dwr通过这个方法对传入的参数生成与servlet进行交互的javascript语句,它做了很多的工作以保证你的提交是真正的有效,比如判断客户的浏览器是支持XMLHttpRequest还是支持ActiveXObject,如果两种方式都不行它还会采取iFrame提交的方式与服务器进行交互获取数据

3、_stateChange DWREngine在判断数据传输完成之后,会根据返回的字符串构造成一个对象

你可以通过修改下面的javascript语句获取返回的javascript对象和你的页面进行交互显示

在util.js文件定义了一个DWRUtil对象,里面主要有对select的处理和table的处理的方法,具体的使用就不在这里说明

多个servlet ,每个servlet 对应一个或多个dwr.xml

dwr-invoker

uk.ltd.getahead.dwr.DWRServlet

dwr-invoker1

uk.ltd.getahead.dwr.DWRServlet

config-admin

WEB-INF/dwr1.xml

debug

true

dwr-invoker

/dwr/*

dwr-invoker1

/dwr1/*

在这种情况下,我们可以根据J2EE security 来控制权限,针对不同url, 加不同的角色。

dwr.xml的配置

标签中包括可以暴露给javascript 访问的东西。

标签中指定javascript 中可以访问的java 类,并定义DWR 应当如何获得要进行远程的类的实例。creator="new" 属性指定java 类实例的生成方式,new 意味着DWR 应当调用类的默认构造函数来获得实例,其他的还有spring 方式,通过与IOC 容器Spring 进行集成来获得实例等等。javascript=" testClass " 属性指定javascript代码访问对象时使用的名称。

标签指定要公开给javascript 的java 类名。

标签指定要公开给javascript 的方法。不指定的话就公开所有方法。

标签指定要防止被访问的方法。

学习心得

Dwr框架搭建

1.将dwr架包导入到项目的web-inf/lib目录下

2.配置说明:

1).首先在web.xml中添加如下语句。

dwr-invoker

org.directwebremoting.servlet.DwrServlet

debug

true

pollAndCometEnabled

true

allowGetForSafariButMakeForgeryEasier

true

crossDomainSessionSecurity

false

config-common

WEB-INF/dwr-common.xml

config-system

WEB-INF/dwr-system.xml

config-converter

WEB-INF/dwr-converter.xml

config-wom

WEB-INF/dwr-wom.xml

3

dwr-invoker

/dwr/*

在这种配置下,param-name的值必须以config开头。param-name可以有>=0个。如果没有param-name,那么将会读取WEB-INF/dwr.xml。如果有大于零个param-name,那么

WEB-INF/dwr.xml文件将不会被读取。

在配置中的debug相对于在项目开发中很重要,因为dwr拥有一个检测功能,检测你写的功能是否能够实现;只有在debug为true的时候才可以让你在你的上下文下面输入dwr直观的检测你所写的东西;举个例子:如果我的项目url是http://localhost:8080/test/index.jsp那么我在地址栏输入http://localhost:8080/test/dwr即可出现一张检测页面,请注意生产环境应该Debug为false,以免在项目上线时出现安全漏洞;

2). 新建一个dwr.xml文件,和web.xml同目录,dwr.xml文件的配置信息如下:

"-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"

"https://www.doczj.com/doc/a517868939.html,/dwr/dwr30.dtd">

scope="application">

这个创造器会查找spring的中配置的Bean,用Spring去创建它们。如果你已经在使用Spring,那么这个创造器会非常有用

寻找你的Spring配置:

有三种方式寻找配置文件:

1.ContextLoaderListener

最简单的方式是使用org.springframework.web.context.ContextLoaderListener。你不必使用所有的Spring-MVC功能,只需要这个Listener就够了,所以这是个不错的方案。你需要在WEB-INF/web.xml中做如下配置:

contextConfigLocation

/WEB-INF/classes/beans.xml

org.springframework.web.context.ContextLoaderListener

2.使用location*参数

如果你要在dwr.xml中指定使用哪些bean,你可以使用location*参数。你可以指定任意多个文件,只要参数以location开始并且唯一即可。例如:location-1, location-2。这些location被用做Spring的ClassPathXmlApplicationContext的参数:

...

3.直接设置BeanFactory

SpringCreator有一个静态方法setOverrideBeanFactory(BeanFactory)用来通过编程的方式直接设置BeanFactory。

4.使用Spring注解,如:

@Service("auditingDwr")//这里的名字和dwr配置文件中节点中子节点的中value值一致,否则会报错

public class AuditingDwr {

}

//对应JavaScript文件名,即:JDate.js在这个文件中有一个名为JDate的JavaScript对象

//对应Java类。

creator属性的值可以是new,struts,spring......

javascript="DWRUser" 表示实例转换成javascript语言后以DWRUser命名,前台页面可以通过代码()来调用param元素的name属性值可以是class,beanName等,此处用beanName,value得值是定义在applicationContext.xml中某个bean的id值或者注解的属性值。

然后启动服务访问:http://localhost:8080/应用名/dwr (如果是ROOT方式部署的,可以省去应用名)

到此框架就搭建好了

具体使用

1.被映射的JavaBean对象中方法的修饰符只有为Public才可以被暴露出来,private ,protected,package都不会暴露,支持继承体系,如果当前被映射的Bean有父类中提供了某Public方法,该方法也会暴露出来。Bean中的属性是不会暴露出来的。

另外还可以在dwr.xml 中明确描述那些公共的方法可以暴露给外界。如: 表示把com.dwr.test.Student中的getUserName()方法暴露出来。如果不写配置,表示把所以的Public方法都暴露,如果写了则只暴露明确指定的方法。

2.

在需要使用Dwr框架直接范文JavaBean的Jsp页面中添加如上三条语句。/dwr/engine.js,/dwr/util.js是固定的,是Dwr的脚本驱动Js和常用的工具类用来对返回的信息加工处理的。/dwr/interface/Student.js是用户需要直接访问的JavaBean对应的JavaScript映射。注意路径

的书写,以及相对位置,这几个文件的层次结构是固定的。并且应用在部署的时候要选择Root方式,否则找不到路径。

3.

前面说过:/dwr/interface/Student.js中有一个和Student同名的对象。即:Student。所以在调用这个Js中方法时需要加上这个对象名,

Student.getUserName(reply),这样处理是为了避免在引入两个Bean,他们对应的JavaScript映射文件中出现相同的函数名情况下的调用混乱。

Student.getUserName(reply)

在Student.js文件中对应着:

Student.getUserName = function(callback) {

dwr.engine._execute(Student._path, 'Student', 'getUserName', callback);

}

可见reply参数是必须的,而且这个参数是一个function类型。用来接受从后台返回来的值。返回的值就存放在变量data中,我们自己的Javascript的最后需要的处理的值就是data.

函数reply的作用就是被回调并带回用户所需的值。可以把这个方法设置为通用方法。统一取得值,放到全局变量中。如本例中accessRemoteData.js文件中的getRemoteData方法。

4.

AJAX是异步实现的,并且AJAX确实是为了异步的实现才引入近来的。但是,AJAX仍然也支持同步的调用。在纯粹的XMLHttpRequest中可以设置调用是否是异步的。XMLHttpRequest 的open函数是有一个是否同步参数,如下:

XMLHttpRequest.open(String method, String URL, boolean asynchronous)

其中的asynchronous就是是否同步的参数了。

在DWR的engine.js文件,有setAsync方法,就是设置调用是否是同步的,还是异步的。

dwr.engine.setAsync(false); 设置为同步运行.

dwr.engine.setAsync(true); 设置为异步运行.

同步模式:

异步模式:

A;—>异步线程

|

B;

具体表现为:在A语句体中启动了一个异步线程,到后台获取信息。如果为异常模式,在启动A异步线程之后,B继续执行。

如果为同步模式:在启动A异步线程之后,B并不执行,直到后台获取信息的动作结束,并返回后才执行。

5.

把JOPO对象反转成JavaScript的对象。match表示对这个包下面所有的JOPO都可以转换。之前说了:进行远程方法调用时,需要传递一个回调函数,用来取回自己所需要的值,最后这个值付给了回调函数的形参变量data

如果调用的方法是Student.getUser(callback).那么返回的data是“Object”类型。如果User 对象有userName,password属性,那么就可以直接的https://www.doczj.com/doc/a517868939.html,erName ,data.password来取得对象(JavaScript对象)中的值。而这个JavaScrip对象,User就是Conver过来的。

如果返回的是一个普通POJO,此时data就代表Conver过来的POJO对象,那么可以直接由data.属性名来得到对应POJO中的值。

如果返回的是一个List,此时data就代表Conver过来的List对象,用data[i]来取得List中下标为i的对象。如果取到的对象还是一个POjO,那么继续按照前一种方法处理。

如果返回的是一个Map,此时data就代表Conver过来的Map对象,用data.key1来取得"Key1"对应的对象,https://www.doczj.com/doc/a517868939.html,erName;

DWR的convert就是用来将server端方法执行后的结果从java的类型转换成JS形式到client端,

或者将client端发过来的script函数调用中的参数转换成java的对象类型

前台与后台交互使用示例

2.调用有简单返回值的java方法

2.1、dwr.xml的配置

配置同1.1

create>

allow>

dwr>

2.2、javascript中调用

首先,引入javascript脚本

其次,编写调用java方法的javascript函数和接收返回值的回调函数Function callTestMethod2(){

testClass.testMethod2(callBackFortestMethod2);

} Function callBackFortestMethod2(data){

//其中date接收方法的返回值

//可以在这里对返回值进行处理和显示等等

alert("the return value is " + data);

} 其中callBackFortestMethod2是接收返回值的回调函数

3、调用有简单参数的java方法

3.1、dwr.xml的配置

配置同1.1

create>

allow>

dwr>

3.2、javascript中调用

首先,引入javascript脚本

其次,编写调用java方法的javascript函数

Function callTestMethod3(){

//定义要传到java方法中的参数

var data;

//构造参数

data = “test String”;

testClass.testMethod3(data);

}

4、调用返回JavaBean的java方法

4.1、dwr.xml的配置

create>

convert>

allow>

dwr>

标签负责公开用于Web远程的类和类的方法,标签则负责这些方法的参数和返回类型。convert元素的作用是告诉DWR在服务器端Java 对象表示和序列化的JavaScript之间如何转换数据类型。DWR自动地在Java和JavaScript表示之间调整简单数据类型。这些类型包括Java原生类型和它们各自的封装类表示,还有String、Date、数组和集合类型。DWR也能把JavaBean转换成JavaScript 表示,但是出于安全性的原因,要求显式的配置,标签就是完成此功能的。converter="bean"属性指定转换的方式采用JavaBean命名规范,match=""com.dwr.TestBean"属性指定要转换的javabean名称,标签指定要转换的JavaBean属性。

4.2、javascript中调用

首先,引入javascript脚本

其次,编写调用java方法的javascript函数和接收返回值的回调函数

Function callTestMethod4(){

testClass.testMethod4(callBackFortestMethod4);

} Function callBackFortestMethod4(data){

//其中date接收方法的返回值

//对于JavaBean返回值,有两种方式处理

//不知道属性名称时,使用如下方法

for(var property in data){

alert("property:"+property);

alert(property+":"+data[property]);

}

//知道属性名称时,使用如下方法

alert(https://www.doczj.com/doc/a517868939.html,ername);

alert(data.password);

} 其中callBackFortestMethod4是接收返回值的回调函数

5、调用有JavaBean参数的java方法

5.1、dwr.xml的配置

配置同4.1

create>

convert>

allow>

dwr>

5.2、javascript中调用

首先,引入javascript脚本

其次,编写调用java方法的javascript函数

Function callTestMethod5(){

//定义要传到java方法中的参数

var data;

//构造参数,date实际上是一个object

data = { username:"user", password:"password" }

testClass.testMethod5(data);

}

6、调用返回List、Set或者Map的java方法

6.1、dwr.xml的配置

配置同4.1

create>

convert>

allow>

dwr>

注意:如果List、Set或者Map中的元素均为简单类型(包括其封装类)或String、Date、数组和集合类型,则不需要标签。

6.2、javascript中调用(以返回List为例,List的元素为TestBean)

首先,引入javascript脚本

其次,编写调用java方法的javascript函数和接收返回值的回调函数

Function callTestMethod6(){

testClass.testMethod6(callBackFortestMethod6);

} Function callBackFortestMethod6(data){

//其中date接收方法的返回值

//对于JavaBean返回值,有两种方式处理

//不知道属性名称时,使用如下方法

for(var i=0;i

for(var property in data){

alert("property:"+property);

alert(property+":"+data[property]);

}

} //知道属性名称时,使用如下方法

for(var i=0;i

alert(https://www.doczj.com/doc/a517868939.html,ername);

alert(data.password);

} }

7、调用有List、Set或者Map参数的java方法

7.1、dwr.xml的配置

create>

convert>

allow>

import java.util.List;

import com.dwr.TestClass;

import com.dwr.TestBean;

TestClass.testMethod7(List);

]]>

signatures>

dwr>

标签是用来声明java方法中List、Set或者Map参数所包含的确切类,以便java 代码作出判断。

7.2、javascript中调用(以返回List为例,List的元素为TestBean)

首先,引入javascript脚本

其次,编写调用java方法的javascript函数

Function callTestMethod7(){

//定义要传到java方法中的参数

var data;

//构造参数,date实际上是一个object数组,即数组的每个元素均为object

data = [

{

username:"user1",

password:"password2"

},

{

username:"user2",

password:" password2"

}

];

testClass.testMethod7(data);

}

注意:

1、对于第6种情况,如果java方法的返回值为Map,则在接收该返回值的javascript回调函数中如下处理:

function callBackFortestMethod(data){

//其中date接收方法的返回值

for(var property in data){

var bean = data[property];

alert(https://www.doczj.com/doc/a517868939.html,ername);

alert(bean.password);

}

} 2、对于第7种情况,如果java的方法的参数为Map(假设其key为String,value为TestBean),则在调用该方法的javascript函数中用如下方法构造要传递的参数:

function callTestMethod (){

//定义要传到java方法中的参数

var data;

//构造参数,date实际上是一个object,其属性名为Map的key,属性值为Map的value data = {

"key1":{

username:"user1",

password:"password2"

},

"key2":{

username:"user2",

password:" password2"

}

};

testClass.testMethod(data);

} 并且在dwr.xml中增加如下的配置段

import java.util.List;

import com.dwr.TestClass;

import com.dwr.TestBean;

TestClass.testMethod7(Map);

]]>

signatures>

3、由以上可以发现,对于java方法的返回值为List(Set)的情况,DWR将其转化为Object数组,传递个javascript;对于java方法的返回值为Map的情况,DWR将其转化为一个Object,其中Object的属性为原Map的key值,属性值为原Map相应的value值。

4、如果java方法的参数为List(Set)和Map的情况,javascript中也要根据3种所说,构造相应的javascript数据来传递到java中。

使用dwr与javascript映射的java类(简称为j类),映射的javascript对象(简称为s对象)

1)j类只可以提供传递参数的方法要传递的参数必须在方法体内部构建(也就是说不能像Bean那样先set再get出来)

该方法的形参列表不能使用后台产生的值或者对象,因为方法是在js中调用的如果要使用后台产生的值或者对象来创建传递的参数

可以先将值和对象放在session中然后在方法体内从session中提取具体方法如下:public List getShowImgs() {

HttpServletRequest req = WebContextFactory.get().getHttpServletRequest();

if (req.getSession().getAttribute("showImgs") != null){

return (List) req.getSession().getAttribute("showImgs");}

else

return null;

}

2)s对象使用的页面必须导入dwr必须的js文件,且必须按如下顺序导入:

s对象获取参数的方法必须使用回调函数来接收参数

DWR的测试及生成的工具方法

访问http://localhost:8080/dwr,上面列出了在dwr.xml里面定义的方法,POJO没有列出

DWR util.js 学习

util.js包含一些有用的函数function,用于在客户端页面调用.

主要功能如下:

1、$() 获得页面参数值

2、addOptions and removeAllOptions 初始化下拉框

3、addRows and removeAllRows 填充表格

4、getText 取得text属性值

5、getValue 取得form表单值

6、getValues 取得form多个值

7、onReturn

8、selectRange

9、setValue

11、s etValues

11、toDescriptiveString

12、useLoadingMessage

13、Submission box

1、$()函数

IE5.0不支持

$ = document.getElementById

取得form表单值

var name = $("name");

2、用于填充 select 下拉框 option

a、如果你想在更新select 时,想保存原来的数据,即在原来的select 中添加新的option:

var sel = DWRUtil.getValue(id);

DWRUtil.removeAllOptions(id);

DWRUtil.addOptions(id,...);

DWRUtil.setValue(id,sel);

demo:比如你想添加一个option:“--请选择--”

DWRUtil.addOptions(id,["--请选择--"]);

DWRUtil.addOptions()有5中方式

Simple Array Example: 简单数组

例如:

Array array = new Array[ 'Africa', 'America', 'Asia', 'Australa sia', 'Europe' ];

DWRUtil.addOptions("demo1",array);

Simple Object Array Example 简单数组,元素为beans

这种情况下,你需要指定要显示 beans 的 property 以及对应

的 bean 值

例如:

public class Person {

private String name;

private Integer id;

pirvate String address;

public void set(){……}

public String get(){……}

}

DWRUtil.addOptions("demo2",array,'id','name');

其中id指向及bean的id属性,在optiong中对应value,name指向bean的name属性,对应下拉框中显示的哪个值.

Advanced Object Array Example 基本同上

DWRUtil.addOptions( "demo3", [{ name:'Afric a', id:'AF' },

{ name:'America', id:'AM' },

{ name:'Asia', id:'AS' },

{ name:'Australasia', id:'AU' },

{ name:'Europe', id:'EU' }],'id','name');

Map Example 用制定的map来填充 options:

如果 server 返回 Map,那么这样处理即可:

DWRUtil.addOptions( "demo3",map);

其中 value 对应 map keys,text 对应 map values;

相关文档 最新文档