版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
DWR中文文档(入门到进阶)第1章.DWR入门1.1简介DWR是一个可以允许你去创建AJAXWEB站点的JAVA开源库它可以让你在浏览器中的Javascript代码调用Web服务器上的Java代码,就像在Java代码就在浏览器中一样。DWR包含2个主要部分:一个运行在服务器端的JavaServlet,它处理请求并且向浏览器发回响应。运行在浏览器端的JavaScript,它发送请求而且还能动态更新网页。DWR工作原理是通过动态把Java类生成为Javascript它的代码就像Ajax魔法一样你感觉调用就像发生在浏览器端,但是实际上代码调用发生在服务器端,DWR负责数据的传递和转换。这种从Java到JavaScript的远程调用功能的方式使DWR用起来有种非常像RMI或者SOAP的常规RPC机制而且DWR的优点在于不需要任何的网页浏览器插件就能运行在网页上。Java从根本上讲是同步机制然而AJAX却是异步的所以你调用远程方法时当数据已经从网络上返回的时候,你要提供有反调(callback)功能的DWR。这个图片显示了DWR如何选择一个下拉列表的内容作为JaaScript的onclick事件的结果。DWR动态在JavaScript里生成一个AjaxService类去匹配服务气端的代码由eventHandler去调用它,然后DWR处理所有的远程细节,包括倒置(converting)所有的参数以及返回Javascript和Java之的值在示例中先在eventHandler方法里调用AjaxService的getOptions()方法然后通过反调(callback)方法populateList(data)得到返回的数据其中data就是String[]{"1","2",""}最后再使用DWRutiity把data加入到下拉列表。好了,DWR介绍完了,现在大家肯定很想知道如何做出第一个DWR吧!然后我们在下一章节以一个HelloWorld示例带领大家入门。8/921.2第一个DWR程序:HelloWorld有2中方法可以帮助你入门DWR一个方法是\h去下载WAR文件并且去完整看一下代码但是这样并不能帮助你发现DWR是如何简单地集成到你当前地WEB应用,所以以下几个简单地步骤推荐看一下:1.2.1将DWR放入你的工程1)从官方网\h站下载dr.jar包。然后将它放在你ebapp的WEB-INF/lib目录下。2)将下载的dr-版本号-src.zip\java\org\directwebremoting内的engine.js和util.js放入WEB应用中,比如js文件夹下。1.2.2编辑配置文件1.web.xml以下几行代码必须被添加到WEN-INF/e.xml文件中。注意,要把<servlet>和其他<servlet>放在一起,<servlet-mapping>要和其他<servlet-mapping>放在一起<servlet><servlet-name>dwr-invoker</servlet-name><servlet-class>org.directwebremoting.servlt.DrServlet</servlet-class><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>2.dwr.xml在eb.ml的同一目录下,创建dr.xml,并且将要被调用的java类写入其中。<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEwrPUBLIC"-//GetAheadimited//DTDDirectWebRemoting2.0//EN""http://www.getahead.ltd.uk/dwr/dwr20.dtd"><dwr><allow><createcreator="new"javascript="service"><paramname="class"value="helloWorld.Service"/></create></allow></dwr>9/921.2.3编写service就像没有dr一样,写一个简单类并加一个方法是packagehelloWorld;publicclassService{publicStringsayHello(StringyourName){//可以是访问数据库的复杂代码return"HelloWorld"+yourName;}}1.2.4测试DWR将代码放入应用服务器(比如Tomcat),启动。然后在地址栏输\h入http://localhost:8080/你的工程/dr然后点击service,会看到刚才写的sayHelo()的方法,输入自己的名字然后点击“Execute”,如果发现确实是正确的返回结果,说明测试通过了,可以进入下一步了。10/921.2.5编写一个jsp接下来最后一步就是创建一个jsp文件1)要引用几个dr的js其中engine.js必须要如果需要用到dr提供的一些方便的工具要引用util.js2)然后还要引用dwr自动生成的js,dr/interface/service.js,注意js名字要和dr.xml配置的一样3)js里的service.sayHllo和java类的那个有一点区别,多了个参数,用来callback返回的数据<%@pagelanguage="java"pageEncoding="UTF-8"%><html><head><title>MyJSP'first_dwr.jsp'startingpage</title><scripttype='text/javascript'src='js/util.js'></script><scripttype='text/javascript'src='js/engine.js'></script><scripttype='text/javascript'src='dwr/interface/service.js'></script><scripttype="text/javascript">functionfirstDwr(){service.sayHello("Jorwen",callBackHello);}functioncallBackHello(data){alert(data);}</script></head>11/92<body><inputtype="button"name="button"value="测试"nclick="firstDwr()"></body></html>地址栏输\h入http://localhost:8080/你的工程/first_dr.jsp显示的结果如下:1.3本章总结相信看了此章节大家一般都能做出这个实例来也算是DWR刚入门了在以后的教程里将详细介绍DWR各个功能帮助大家能开发出任何Ajax需求的功能来更多进阶的例子可以参考范例精讲您也可以通过看范例学习DWR然后有疑问再查看该文档的相关章节。12/92第2章.web.xml配置2.1主要配置要加入到你的eb.xml最少的代码就是简单地去申明DWRservlet,没有它DWR就不起作用。<servlet><servlet-name>dwr-invoker</servlet-name><servlet-class>org.directwebrmoting.servlet.DrServlet</servlet-class></servlet><servlet-mapping><servlet-name>dwr-invoker</servlet-name><url-pattern>/dwr/*</url-pattern></servlet-mapping>在DWR2.x里,DrServlets是类org.directebrmoting.servlet.DrServlet,尽管uk.ltd.getahead.dr.DWRServlet仍然可以用。在DWR1.x你不得不使用后者。有些额外的servlet参数,在有些地方很重要。尤其debug参数这个扩展DWR的标准结构是使用<init-params>。放在<servlet>内,就像如下使用<servlet><servlet-name>dwr-invoker</servlet-name><servlet-class>org.directwebrmoting.servlet.DrServlet</servlet-class><init-param><param-name>debug</param-name><param-value>true</param-value></init-param></servlet>另外,启动服务时,如果报如下错。java.lang.IllegalArgumentException:DefaultContainercan'tfindaclasses是DWR2.0加入了JDK5的注释(annotations).DrServlet初始化的时候会去检查注释的类找不到就抱错了。如果你不用annotations也可以忽略掉这个错误。不过看起来总是不爽。解决方案如下<servlet><servlet-name>dwr-invoker</servlet-name><servlet-class>org.directwebrmoting.servlet.DrServlet</servlet-class><init-param>13/92<param-name>debug</param-name><param-value>true</param-value></init-param><init-param><param-name>classes</param-name><param-value>java.lang.Object</param-value></init-param></servlet>2.2常用<init-param>参数列表2.2.1安全参数\hallowGetForSafaiButMakeForgerEasier开始版本:2.0默认值:false描述:设置成true使DWR工作在Safari1.x,会稍微降低安全性。\hcrossDomainSesionSecurity开始版本:2.0默认值:true描述:设置成fase使能够从其他域进行请求。注意,这样做会在安全性上有点冒险,参考一下这\h篇文章,在没有理解这个后果前不要设置成为false。\hdebug开始版本:1.0默认值:false描述:设置成true使DWR能够debug和进入测试页面scriptSessionTimeout开始版本:2.0默认值:180000(30分钟)描述:scriptsessin的超时设置maxCllCount开始版本:2.0rc2和1.1.4默认值:20描述:一次批量(btch)允许最大的调用数量。(帮助保护Dos攻击)2.2.2Ajax服务器加载时保护参数pollndCometEnabled开始版本:2.014/92默认值:false描述:设置成true能增加服务器的加载能力,尽管DWR有保护服务器过载的机制。maxWaitingThreads开始版本:2.0默认值:100描述:最大等待线程数量。preStreamWaitTime开始版本:2.0默认值:2900(单位:毫秒)描述:对一个打开流前的反应,等待的最大时间postStreamWaitTime开始版本:2.0默认值:100(单位:毫秒)描述:对一个打开流后的反应,等待的最大时间2.2.3其他参数ignoreLastModified开始版本:2.0默认值:false描述:默认值支持最后修改,这样就允许服务器端对客户端请求较少资源。设置为true就能屏蔽支持。scriptCompressed开始版本:1.1默认值:false描述:DWR够执行简单的压缩,设置为true可以激活此功能。另外还有一个未公开的有关系的重要参数“compressioLeve”,此参数允许你配置压缩类型。查HYPERLINK\h看这里得到更多详细资料。sessionCookieName开始版本:2.0默认值:JSESSIONID描述:DWR过检查文档和提取当前sessionID支持URL重写。一些servlet引擎使用非标准的cookie名。参数允许你改变默认值。welcomFiles开始版本:2.0默认值:inde.html,index.htm,inde.jsp描述:类似于web.xml的<elcome-file-list>标签15/922.3日志配置DWR工作在JDK1.3中不支持java.util.logging,但我们并不强迫任何人都去使用commons-logging或者log4j所以在使用HttpServlet.log()方法时DWR将正常工作如果没有日志类的话然而如果DWR可以使用,那么它将使用日志。Commom-Logging由于大多数servlet容器都使用它几乎每个都将使用commons-loggin所以如果你的ebapp不明确使用commons-logging,它将被默认设为可以使用。在这些日志将被一些配置文件所约束,比如java.util.logging或者log4j,可以去查看他们各自的文档获得详情。HttpServlet.log()如果你正在使用HttpServlet.log(),以下的代码用来控制DWR日志<init-param><param-name>logLevel</param-name><param-value>DEBUG</param-value></init-param>值可以是:FATAL,ERROR,WARN(默认),INFO,DEBUG2.4多个dwr.xml配置和J2EE角色定义一般来说只需要一个dr.ml文件,并且会被设为默认位置WEB-INF/dr.xml。所以你不需要配置。有3个原因说明你为何需要指定不同位置的dr.ml文件:你想保持dr.xml的文件请参照下面的例子<param-value>WEB-INF/classes/com/yourco/dwr/dwr.xml</param-value>你可以有很多的远程方法类并且希望指定文件。在这个例子里将指定不同文件开始配置,不同的param-name将重复多次DWR将轮流读取它们。DWR能够使J2EEURL具有给与不同用户组不同权限的安全机制。通过起不同名字,URL和权限。就像如下例子去使用<init-param><param-name>config*****</param-name><param-value>WEB-INF/dwr.xml</param-value><description>Whatconfigfiledoweuse?</description></init-param>16/92用一个字符串”confi”作为开始,设置param-nam,每个param-name必须不同。<servlet><servlet-name>dwr-user-invoker</servlet-name><servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class><init-param><param-name>config-user</param-name><param-value>WEB-INF/dwr-user.xml</param-value></init-param></servlet><servlet><servlet-name>dwr-admin-invoker</servlet-name><servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class><init-param><param-name>config-admin</param-name><param-value>WEB-INF/dwr-admin.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>dwr-admin-invoker</servlet-name><url-pattern>/dwradmin/*</url-pattern></servlet-mapping><servlet-mapping><servlet-name>dwr-user-invoker</servlet-name><url-pattern>/dwruser/*</url-pattern></servlet-mapping><security-constraint><display-name>dwr-admin</display-name><web-resource-collection><web-resource-name>dwr-admin-collection</web-resource-name><url-pattern>/dwradmin/*</url-pattern></web-resource-collection><auth-constraint><role-name>admin</role-name></auth-constraint></security-constraint><security-constraint><display-name>dwr-user</display-name>17/92<web-resource-collection><web-resource-name>dwr-user-collection</web-resource-name><url-pattern>/dwruser/*</url-pattern></web-resource-collection><auth-constraint><role-name>user</role-name></auth-constraint></security-constraint>2.5插件配置大多数DWR的功能是可以作为插件的,所以就通过替换默认的类可以改变DWR的功能。你可以通过包含<init-param>去覆盖默认的实现。举个例子:<init-param><param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name><param-value>com.example.MyCustomServerLoadMonitor</param-value></init-param>没有规定我们越过主要的版本丢弃这些接口,但是我们将尝试提供简单的升级路径。DWR2.0插件 org.directeremoting.Container org.directeremoting.WebContextFactor.WebContextBuilder org.directeremoting.ServerContextFactory.ServerContextBuilder org.directeremoting.servlet.UrlProcessor org.directeremoting.extend.AccessControl org.directeremoting.extend.AjaxFilterManager org.directeremoting.extend.ConverterManager org.directeremoting.extend.CreatorManager org.directeremoting.extend.DebugPageGenertor org.directeremoting.extend.HtmlCallMarshallerorg.directeremoting.extend.HtmlPollHandleror.directeremoting.etend.PageNormalizer org.directeremoting.extend.PlainCallMarshaller org.directeremoting.extend.PlainPollHandler org.directeremoting.extend.Remoter org.directeremoting.extend.ScriptSessionManager org.directeremoting.extend.ServerLoadMonitor默认的实现大多数在org.directebremoting.impl包,细节是在ContainerUtil.setupDefaults()指定的。18/92DWR1.1插件 uk.ltd.getahead.dr.AccessControl uk.ltd.getahead.dr.Configuration uk.ltd.getahead.dr.ConverterManager uk.ltd.getahead.dr.CreatorManager uk.ltd.getahead.dr.Processor uk.ltd.getahead.dr.ExecutionContet默认的实现大多数在uk.ltd.getahead.dr.impl包2.6测试模式配置通过添加如下参数,设置debug测试模式<init-param><param-name>debug</param-name><param-value>true</param-value></init-param>在debug模式里DWR将为每个allow的类(请看下面的dr.xml配置章节)生成测试页面这些能变得非常有用帮助了解DWR能做什么和如何工作这个模式也能警告你以防止javascript的保留字或者重载问题。然而这个模式不应该被用在现场部署,因为他能给黑客或者攻击者许多关于服务器的详细信息。19/92第3章.dw.xml配置3.1纵览dr.ml是你用来配置DWR的文件,默认是将其放入WEB-INF文件夹。创建一个dwr.xml文件dr.ml有如下的结构:<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEwrPUBLIC"-//GetAheadimited//DTDDirectWebRemoting2.0//EN""http://www.getahead.ltd.uk/dwr/dwr20.dtd"><dwr><!--仅当需要扩展DWR时才需要--><init><creatorid="..."class="..."/><converterid="..."class="..."/></init><!--没有它DWR什么也做不了--><allow><createcreator="..."javascript="..."/><convertconverter="..."match="..."/></allow><!--有必要告诉DWR方法签名--><signatures>...</signatures></dwr>3.2<init>标签这个初始化部分申明被用来创建远程beans而且这个类能被用来以某种过程转换大多数例子你将不需要用它,如果你想去定义一个新的Creator或者Converter,就要在此被申明。在init部分里有了定义只是告诉DWR这些扩展类的存在,给出了如何使用的信息。这时他们还没有被使用这种方式很像Java中的import语句多数类需要在使用前先import一下但是只有import语句并不表明这个类已经被使用了。每一个creator和converter都用id属性,以便后面使用。20/923.3<allow>标签allow部分定义了DWR能够创建和转换的类。3.3.1Creator每一个在类中被调用的方法需要一个<create…>有若干类型的creator使“ne关键字或者Spring框架等。create元素是如下的结构<allow><createcreator="..."javascript="..."scope="..."><paramname="..."value="..."/><authmethod="..."role="..."/><excludemethod="..."/><includemethod="..."/></create>...</allow>1.creator属性1).new:Java用“new”关键字创造对象是DWR默认的creator,如下所示<createid="new"class="org.directwebremoting.create.NewCreator"/>没有必要把它加入dr.ml,它已经在DWR内部文件了。这个creator将使用默认构造器创建类的实例,以下是用new创建器的好处 安全:DWR创造的对象生存的时间越短,多次调用中间的值不一致的错误机会越少。 内存消耗低:如果你的站点用户量非常大,这个创造器可以减少VM的内存溢出。2).none:它不创建对象,看下面的原因。(v1.1+)none创建器不创建任何对象,它会假设你不须要创建对象。有2个使用的原因: 你可能在使用的scope不是"page(看上面)并在在前面已经把这个对象创建到这个scope中了,这时你就不需要再创建对象了。 还有一种情况是要调用的方法是静态的这时也不需要创建对象DWR会在调用创建器之前先检查一下这个方法是不是静态的。对于上诉两种情况,你仍然需要class参数,用来告诉DWR它是在操作的对象类型是什么。21/923).scripted:通过BSF使用脚本语言创建对象例如BeanShell或Groovy。要使用这个创造器,你需要把一些辅助库放到WEB-INF/lib文件夹下:比\h如BSF的jar包,你要用\h的脚本语言的jar包。new创造器在DWR中已经默认声明了:<creatorid="script"class="uk.ltd.getahead.dr.create.ScriptedCreator"/>这个创造器用BSF来执行脚本得到Bean,例如:<allow>...<createcreator="script"javascript="EmailValidator"><paramname="language"value="beanshell"/><paramname="script">importmons.validator.EmailValidator;returnEmailValidator.getInstance();</param></create>...</allow>script创造器有如下参数:参数langagescriptscriptPathreloaableclass
DWR版本 描述1.0 脚本语言,字符串,例如'beashell'.(必需)1.0 要执行的脚本。(必需,除非scriptPath参数存在)1.1 脚本文件路径。(必需,除非script参数存在)1.1 是否检测脚本文件的改动,以重新加载(可选,默认true)1.0 创造出对象的类型(可选).如果没有DWR通过创造器得到类型。注意:当一个类是用script创造出来的并且scope是session或application如果你的脚本改变sesson中的类和script中的类就不一致了这样会出现错误虽然eb容器不用重启但是用户需要先登出(或以某种方式清空session),然后再登录。当clazz参数不为空并且用来创造新实例DWR简单的调用class.newInstance()方法这种方法是没问题的除非脚本正在用某个参数创建一个类或者调用某个函数来配置这个类。不幸的是每次请求都要重新运行script并造成上面的问题。22/924).spring:通过Spring框架访问Bean。详情请见DWR与Spring整合5).jsf:使用JSF的Bean。(v1.1+)详情请见DWR与JSF整合6).struts:使用Struts的FormBean。(v1.1+)详情请见DWR与Struts整合7).pageflow:访问Weblogic或Beehive的PageFlow。(v1.1+)详情请见DWR与Weblogic或Beehive的PageFlow整合8).ejb3:使用EJB3sessionbean。(v2.0+)一个正在实验的创造器用来访问EJBSessionbeas直到进行更多的测试和正式的维护否则还不能作为产品被使用。如果你想写自己的creator,你必须在<init>里注册它。2.javascript属性在浏览器里给你创建的对象命名避免使用JavaScript保留字这个名字将在页面里作为js被导入就像第2章节的那个jsp:dr.ml<createcreator="new"javascript="service"><paramname="class"value="helloWorld.Service"/></create>html/jsp<html><head>…<scripttype='text/javascript'src='dwr/interface/service.js'>…3.scope属性和定义在servlet的scope一样大的范围它允许你指定哪个bean是可以获得的选项可以是appication,session,request和pag。这些值应该已经被开发者们熟悉了。scope选项是可选的,默认为page,使用session请求cookies。目前,DWR还不支持URL重写。23/924.param元素被用来指定创造器的其他参数每种构造器各有不同例如"e"创造器需要知道要创建的对象类型是什么。每一个创造器的参数在各自的文档中能找到。5.include和exclude元素允许一个创造器去限制进入类的方法。一个创造器必须指定include列表或eclude列表之一。如果是include列表则暗示默认的访问策略是"拒绝"iclude中的每个方法就是允许访问的方法如果是exclude列表则暗示默认的访问策略是"允许",exclude中的每个方法就是拒绝访问的方法。比如:<createcreator="new"javascript="Fred"><paramname="class"value="com.example.Fred"/><includemethod="setWibble"/></create>说明你只能在DWR中使用Fred的是setWibble方法。6.auth元素允许你指定一个J2EE的角色作为将来的访问控制检查:<createcreator="new"javascript="Fred"><paramname="class"value="com.example.Fred"/><authmethod="setWibble"role="admin"/></create>7.使用静态方法DWR会在调用创建器之前先检查一下这个方法是不是静态的如果是那么创造器不会被调用很显然这个逻辑适用于所有创造器,尽管如此"null"创造器是最容易配置的。8.使用单例类对于单例类的创建,最好适用BeanShell和BSF来实例化对象。请参考scripted创造器。9.DWR与HttpSessionBindingListenersDWR1.x中存贮已经创造的Bean的方法需要注意,它在每次请求时都会调用相同的setAttribute()方法。就是说,如果一个Bean在dr.xml中的声明周期设置为session,再每次调用bean中的方法时,DWR都会执行一次session.setAttribute(yourBean)。这看上去没有什么危害,但是如果你要使用servlet的事件机制的就是说用了HttpSessionBindingListener接口你就会发现valueBound和valueUnbond事件在每次调用时都会发生,而不是你想像的在bean被创建时以及session过期时。DWR2只在第一次创建对象时调用setAttribute()。24/923.3.2Converter我们需要确认所有的参数能被转换许多JDK提供的类型使你能够使用但是你如果要转换你自己的代码,就必须告诉DWR。一般是指JavaBean的参数需要一个<convrt…>标签作为入口。你不需要在dr.xml中<allow>部分的<convert>中定义。它们默认支持。所有主要的类型,boolean,int,doule等等。包装类,Boolean,Integer等等。java.lang.Stringjava.util.Date和java.sql.Times,java.sql.Timestamp。数组(存放以上类型的)集合类型(List,Set,Map,Iteator等等)(存放以上类型的)DOM对象(来自于DOM,OM,JDOM和DOM4J)1.日期转换器如果你有一个String(例如“2001-02-11)在Javascript你想把它转换成Java日期那么你有2种选择,一是使用Date.parse()然后使用DataConverter传入服务器端,还有一种选择是把该String传入,然后用java的SimpleDateFormat(或者其他的)来转换。同样如果你有个Java的Date类型并且希望在HTML使用它你可以先用SimpleDateFormat把它转换成字符串再使用也可以直接传Date给Javascript然后用Javascript格式化第一种方式简单一些尽管浪费了你的转换器,而且这样做也会是浏览器上的显示逻辑受到限制。其实后面的方法更好,也有一些工具可以帮你,例如: \hTheJavascriptToolboxDaeformatter \hWebDevelopersNotesonateformatting2.数组转换器数组实体不太容易理解。默认情况下DWR能转换所有原生类型的数组,还有所有marshallable对象的数组。这些marshallable对象包括前面介绍的String和Date类型。match属性看上去很怪。<convertconverter="array"match="[Z"/><convertconverter="array"match="[B"/><convertconverter="array"match="[S"/><convertconverter="array"match="[I"/><convertconverter="array"match="[J"/><convertconverter="array"match="[F"/><convertconverter="array"match="[D"/><convertconverter="array"match="[C"/><convertconverter="array"match="[L*"/>上面没有解释*的作用-它是通配符表示匹配接下来的所有字符串这也是DWR可以转换任意类型的数组的原因。25/923.bean和对象转换器两个没有默认打开的转换器是Bean和Object转换器。Bean转换器可以把POJO转换成Javascript的接合数组(类似与Java中的Map)或者反向转换这个转换器默认情况下是没打开的因为DWR要获得你的允许才能动你的代码。Object转换器很相似不同的是它直接应用于对象的成员而不是通过getter和setter方法下面的例子都是可以用object来替换bean的来直接访问对象成员。如果你有一个在<create...>中声明的远程调用Bean。它有个一参数也是一个bean,并且这个bean有一个setter存在一些安全隐患,那么攻击者就可能利用这一点。你可以为某一个单独的类打开转换器:<convertconverter="bean"match="your.full.package.BeanName"/>如果要允许转换一个包或者子包下面的所有类,可以这样写:<convertconverter="bean"match="your.full.package.*"/>显而易见,这样写是允许转换所有的JavaBean:<convertconverter="bean"match="*"/>BeanConerter和JaaBans规范用于被BeanConverter转换的Bean必须符合JavaBeans的规范因为转换器用的是Introspection,而不是Reflection这就是说属性要符合一下条件有getter和settersetter有一个参数并且这个参数的类型是getter的返回类型setter应该返回voidgetter应该没有任何参数setter没有重载。以上这些属于常识。就在eclipse里自动为每个属性添加setter,getter那种类型,如果你用的不是JavaBea,那么你应该用ObjectConverter.设置Jaascript变量DWR可以把Javascript对象(又名maps,或联合数组)转换成JavaBean或者Java对象。例子:publicclassRemoted{publicvoidsetPerson(Personp){//...}}publicclassPerson{publicvoidsetName(Stringname){...}publicvoidsetAge(intage){...}//...}26/92如果这个Remoted已经被配置成Creator了,Prsion类也定义了BeanConverter,那么你可以通过下面的方式调用Java代码:varp={name:"Fred",age:21};Remoted.setPerson(p);限制转换器就像你可以在creator的定义中剔出一些方法一样,converter也有类似的定义。限制属性转换仅仅对于Bean有意义,很明显原生类型是不要需要这个功能的,所以只有BeanConverter及其子类型(HibernteBeanConverter))有这个功能。语法是这样的:<convertconverter="bean"match="com.example.Fred"><paramname="exclude"value="property1,property2"/></convert>这就保证了DWR不会调用fred.getProperty1()和fred.getProperty2两个方法另外如果你喜欢"白名单"而不是"黑名单"的话:<convertconverter="bean"match="com.example.Fred"><paramname="include"value="property1,property2"/></convert>安全上比较好的设计是使用"白名单"而不是"黑名单"。访问对象的私有成员通过'objct'转换器的参数的一个名为force的参数,可以让DWR通过反射来访问对象私有成员。语法是这样的:<convertconverter="object"match="com.example.Fred"><paramname="force"value="true"/></convert>直到DWR1.1.3,这里有一个bug,public的field反而不能被发现,所以你需要在public成员上设置force=true。27/924.集合类型转换器有个两个默认的转换器,针对Map和Collection:<convertconverter="collection"match="java.util.Collection"/><convertconverter="map"match="java.util.Map"/>一般来说这些转换器可以递归转换它们的内容。但是也有两点不足之处:仅仅用反射机制是没有方法明确集合里面是什么类型的所以这两个转换器不能把集合里面的东西转换成有意义的Javascript对象。不能明确是那种类型的集合。虽然我们不能让他们自动的起作用,我们可以在dr.xml中用signatures语法声明它们类型,使之正确转换。5.枚举类型转换器枚举类型转换器默认是没有打开的它在Java5中的Enum和Javascript的String之间进行转换这个转换器默认关闭是因为DWR要在转换你的代码之前得到你的同意。枚举类型转换器是DWR1.1版以后才支持的。你可以这样设置来打开这个转换器:<convertconverter="enum"match="your.full.package.EnumName"/>设置Javascript,一个简单的例子。假设你有下面的Java代码:publicclassRemoted{publicvoidsetStatus(Statusp){//...}}enumStatus{PASS,FAIL,}如果Remoted类已经配置好Creator,并且Status枚举类型已经设置了EnumConverter。那么你就可以在javascript中这样调用:Remoted.setStatus("PASS");28/926.DOM对象DWR可以自动转换来之DOM,DOM4J,JDOM和XOM的DOM树。你可以简单得用上面这些类库返回一个Document、Element或者Node,DWR会把他们自动转换成浏览器的DOM对象。在程序启动的时候会有一个常见的关于JDOM转换器的警告,你可以放心的忽略它,除非你要用JDOM:INFO:Missingclassdefforconverter'jdom'.Failedtoloaduk.ltd.getahead.dwr.convert.JDOMConverter.Cause:org/jdom/Document因为DWR没有办法知道你是否想用JDOM,所以这个信息设在INFO级别的。如果你曾经尝试过使用JDOM你会意识到在这种情况下这个转换器不可用的-这也是我们显示这个信息的原因。我相信DWR能同eist-db很好的工作因为它是建立在W3CDOM之上的而DWR也支持这个。29/923.4<signatures>标签DWR使用反射机制在转换过程中找到它应该使用的类型有时候类型的信息无法获得在这种情况下你要在此处用方法签名给予暗示。signatures段使DWR能确定集合中存放的数据类型例如下面的定义中我们无法知道list中存放的是什么类型。publicclassCheck{publicvoidsetLotteryResults(Listnos){...}}signatures段允许我们暗示DWR应该用什么类型去处理。格式对以了解JDK5的泛型的人来说很容易理解。<signatures><![CDATA[importjava.util.List;importcom.example.Check;Check.setLotteryResults(List<Integer>no);]]></signatures>DWR中又一个解析器专门来做这件事,所以即便你的环境时JDK1.3DWR也能正常工作。解析规则基本上会和你预想规则的一样(有两个例外),所以java.lang下面的类型会被默认import。第一个是DWR1.0中解析器的bug,某些环境下不能返回正确类型。所以你也不用管它了。第二个是这个解析器时"阳光(sunyday)"解析器。就是说它非常宽松,不想编译器那样严格的保证你一定正确。所以有时它也会允许你丢失import:<signatures><![CDATA[importjava.util.List;Check.setLotteryResults(List<Integer>);]]></signatures>30/92将来的DWR版本会使用一个更正式的解析器这个编译器会基于官方Java定义所以你最好不要使用太多这个不严格的东西。signatures段只是用来确定泛型参数中的类型参数。DWR会自己使用反射机制或者运行时类型确定类型,或者假设它是一个String类型。所以:不需要signatures-没有泛型参数:publicvoidmethod(Stringp);publicvoidmethod(String[]p);需要signatures-DWR不能通过反射确定:publicvoidmethod(List<Date>p);publicvoidmethod(Map<String,WibbleBean>p);不需要signatures-DWR能正确的猜出:publicvoidmethod(List<String>p);publicvoidmethod(Map<String,String>p);不需要signatures-DWR可以通过运行时类型确定:publicList<Date>method(Stringp);没有必要让Javascript中的所有对象的key都是String类型-你可以使用其他类型作为key但是他们在使用之前会被转换成String类型。DWR1.x用Javascript的特性把key转换成String。DWR2.0可能会用toString()方法,在服务段进行这一转换。31/92第4章.整合4.1DWR与Servlet有2个Java类你一般需要用在DWR中,是ebContext和WebContetFactory在DWR1.x它们在uk.ltd.getahead.dwr包,DWR2.+在org.directebremoting包这2个类给与你访问标准Httpservlet对象的入口。这些对象是:HttpServletRequestHttpServletResponseHttpSessionServletContetServletConfig4.1.1使用webontext的方法:importuk.ltd.getahead.dwr.WebContext;importuk.ltd.getahead.dwr.WebContextFactory;//WebContextctx=WebContextFactory.get();req=ctx.getHttpServletRequest();处理Httprequest和response做为只读是非常重要的。因为,当Httpheaders也许会通过,那么有些浏览器会忽略它们(比如IE忽略缓存参数)。任何尝试改变Httpbody将会导致DWR错误。WebContext使用一个本地线程变量,所以你能使用以上的代码放在任何地方。也可以看一下DR\h的Java文档,或者详细看一下\hebContext。WebContext代替了DWR1.1中的EecutionContext。4.1.2方法选择在没有写依赖于DWR的代码时,要能够访问Httpservlet对象是可以做到的(比如HttpServletRequest,HttpServletResponse,HttpSession,ServletContextorServletConfig)。DWR将自动填充它。举个例子:publicclassRemote{publicvoidmethod(intparam,ServletContextcx,Strings){...}}32/92然后你将可以从Javascript中通访问它尽管没有ServletContext参数:Remote.method(42,"test",callback);DWR将为你填充这个参数。对这个方法这里有个小小的警告,你要保证你的没有把’callbackfuction’作为第一个参数,而应该把它作为最后一个参数,或者作为元数据对象33/924.2DWR与Spring4.2.1让DWR和Spring一起工作的检查列表1. 确认你用的是最新版的DWRSpring创造器已经有了变化所以你最好检查一下DWR\h的最新版本。2. 确认你的Spring的Bean在DWR外面运行良好。3. 配置DWR和Spring一起工作。(看下面)4. 查看演示页面:http://locahost:8080/[YOUR-WEBAPP]/dr,检查spring的Bean是否出现。DWR对于Spring没有运行期依赖,所以如果你不使用Spring那么Spring的支持不会产生任何影响到。4.2.2SpringCreator这个创造器会在springbeans.xml里查询bean并且会使用Spring去创建它们如果你已经使用Spring,这个创造器会非常有用。否则将完全没有任何用处。要让DWR使用Spring创造器去创建和远程调用beans,要像如下所示:<allow>...<createcreator="spring"javascript="Fred"><paramname="beanName"value="Shiela"/></create></allow>4.2.3找到Spring配置文件有3个方法可以找到Spring配置文件1.ContextLoaderListener最简单的用法使从Spring-MVC里使用org.springframework.web.context.ContextLoaderListener你不必使用整个Spring-MVC去确认这个普遍的解决方案使多么好。只要再你的eb.xml里配置:<context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/classes/beans.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>34/922.使用location参数如果你喜欢指定的beans.xml在你的dr.xml文件中,那么你能使用location参数。你可以指定你希望数量的,必须有唯一的以”location”开头的命名。比如:location-1,location-2。这些locations是作为参数传到Spring的ClassPathXmlApplicationContext:<allow>...<createcreator="spring"javascript="Fred"><paramname="beanName"value="Shiela"/><paramname="location"value="beans.xml"/></create></allow>3.设置beenFactory目录Spring创造器有一个静态的方法setOverrideBenFactory(BeanFactory)这个方法提供一个可编程的方式去覆盖任何BeanFactories。4.2.4使用Spring配置DWRBramSmeets写了一\h个有意思的blog,教你配置DWR使用beans.xml代替WEB-INF/e.xml。我也对于如何在beans.xml中指定dr.xml很感兴趣,尽管这看上去有些Spring传染病的感觉。35/924.3DWR与JSFDWR包括两个JSF的扩展点,一个创造器和一个ServletFilter。4.3.1JSFCreatorDWR1.1中有一个体验版的JsfCreator。你可以在dr.xml中这样使用:<allow>...<createcreator="jsf"javascript="ScriptName"><paramname="managedBeanName"value="beanName"/><paramname="class"value="your.class"/></create>...</allow>这将允许你通过DWR调用ManagedBean。4.3.2ServletFilterDWR/Faces过滤器允许你不在JSF的生命周期里调用FacesContext中的Bean。要使用JsfCreator,你应该把DWR/Faces过滤器加到eb.xml中。<filter><filter-name>DwrFacesFilter</filter-name><filter-class>uk.ltd.getahead.dwr.servlet.FacesExtensionFilter</filter-class></filter><filter-mapping><filter-name>DwrFacesFilter</filter-name><url-pattern>/dwr/*</url-pattern></filter-mapping>这两个需要放在eb.ml中与其他的filter和filter-mapping放在一起。36/924.4DWR与StrutsDWR能够和任何框架结合。这个网站是个极端巧妙的证据,因为它把DWR使用在\hDrupal(PHP)。DWR和Struts整合有2个层次。最基础的层次就是同时使用这两个框架,这是非常容易的,但是这样就不允许在DWR和Struts之间共享Action了。DWR能构调用任何方法,所以你也能从调用一个Strutsaction,除非你不想那么做。ActionForm的内容是什么,当返回ActionForard时DWR怎么做?一个比较好方法是重构你想调用的Action提取出Action的逻辑DWR和你的Action就可以同时调用相同的方法了。4.4.1StrutscreatorDWR1.1增加了一个StrutsCreator。你可以在dr.xml中这样使用:<allow>...<createcreator="struts"javascript="ScriptName"><paramname="formBean"value="formBeanName"/></create>...</allow>这样你就能从DWR调用FormBeans。4.4.2开始顺序如果正在使用Struts创造器那么你应该确保Struts初始化在DWR之前你要保证你在eb.xml里有一个<loa-on-startup>的值,其中Struts的值比DWR设置地要低。37/924.5DWR与Weblogic或PageFlowDWR中有一个创造器可以和Weblogc或者Beehive中的PageFlow一起工作。PagFlowcreatorDWR1.1中加入了一个PageFloCreator。你可以这样使用:<allow>...<createcreator="pageflow"javascript="ScriptName"/>...</allow>38/924.6DWR与Hibernate4.6.1让DWR和Hibernate一起工作的检查列表1. 确保你使用的是最新的DWR。Hibrnate转换器是新东西,所以你需要下\h载最新版本2. 确保你的Hiberante在没有DWR的时候工作正常。3. 如果是Spring和Hibernate一起使用,那么你最好先了解一下如何将整合Spring。4. 配置DWR,使之与Hibernate一起工作。(看下面)。5. 查看演示页面:http://localhost:808/YOUR-WEBAPP/dr,确定Spring的Bean可以出现。4.6.2HibernateBeanConverter除了我们可以决定是否要使用lazyloaded属性,这个转换器非常类似于标准的BeanConverter。在DWR1.1Hibernate转换器被称为“hibernate”并且作用在hibernate2,在DWR2.x有2个转换器被称为“hibernate2”并且作用在hibernate3。使用HibernateBeanConverter也许有点风险,原因如下:结构HibrnateBeanConverter不符合MVC模式所以不能把对象在数据曾和表现曾之间进行隔离。这个风险可以通过在上面加上独立的bean来减轻。性能:DWR试图通过相同的序列化方式来转换所有可以得到的属性(除了DWR仅仅读JavaBean属性的时候)。所以可能会出现通过HTTP序列化了你的整个数据的情况。通常这并不是你想要的。要减少这一风险可以使用BeanConverter(HibernateBeanConverter衍生于它)的排除某些属性的功能,如下所示:<paramname="exclude"value="propertyToExclude1,propertyToExclude2"/>HibrnateBeanConverter会尝试不去读取没有初始化的属性如果你只是想读取所有的东西那么应该使用BeanConverter。建议使用Hibernate3,实际上Hibrnate2的情况,你会发现你得到的都是空的Bean。4.6.3Session管理如果你使用Hibernate对象你需要知道每一个DWR请求都是一个新的Servlet请求所以你需要保证为每个请求打开一个Hiberante的Session。如果你用Spring,那么可以很方便的使用Spring里面的OpenSessionInVieFilter,它可以保证为每个请求打开一个Hiberante的Session。类似的解决方案在其它Frameork中也存在。39/924.7DWR与WebWorkWebWork支持在DWR2.0m3以后才有。要可以通过DWR调用WW的Action,要做两件事。4.7.1配置dwr.xml你必须在dr的配置文件中加入这样的配置:<createcreator="none"javascript="DWRAction"><paramname="class"value="org.directwebremoting.webwork.DWRAction"/><includemethod="execute"/></create><convertconverter="bean"match="org.directwebremoting.webwork.ActionDefinition"><paramname="include"value="namespace,action,method,executeResult"/></convert><convertconverter="bean"match="org.directwebremoting.webwork.AjaxResult"/>这样你AjaxWebWorkAction调用返回一个action实例(而不是文字)。然后你必须包括action对象的转换器定义(package级别或单独action)。<convertconverter="bean"match="your_action_package.*"/>4.7.2在JSP中导入脚本下面这些代码开启DWR调用Action的功能你还要导入DWRActionUtil.js脚本(在你的eb脚本路径中)像这样在JS中调用Action:DWRActionUtil.execute(id,params,callback,[displayMessage]);1.id参数actionUri:要调用action的URI(没有.action).例如:DWRActionUtil.execute('/ajax/TestFM','myform','doOnTextResult');40/92actionDefinitionObject:在xwork.ml中定义的action对象.必须指定下面的内容:namespace:xwork.xml中action的名称空间action:xork.xml中action的名字executeResult:truefalse(是否执行action的结果,如果false直接返回action实例)例如:DWRActionUtil.execute({namespace:'/ajax',action:'TestJS',executeResult:'true'},'data',doOnJSResult,"stream...");2.params参数emptyPrams:传递{}忽略任何参数。例子:DWRActionUtil.execute('/ajax/TestFM',},doOnJSResult,"stream...");fieldId:被转换为action调用参数的字段的id。例子:<inputid="mytext"name="mytext"value="somevalue"type="text"/>DWRActionUtil.execute('/ajax/TestFM','mytext',doOnJSResult,"stream...");formId:表单的id.所有的input值被转换为action调用参数。Note:如果你的action使用了parameter拦截器那么你的action会得到正确的参数值请参考WebWork的文档。3.callback参数callbackFunction:在DWR中,这个函数在请求完毕后调用。callbackObject:在DWR中,callback对象。4.displayMessage参数displaMessage是可选参数,当请求完毕后显示的消息(参考DWR文档)4.7.3高级你可以声明一个pre/postAction处理器,在eb.xml中的一个context-ide初始化参数(dwrActionProcessor)。处理器必须实现org.directwebremoting.ebork.IDWRActionProcessor接口。这个处理器将会在action之前和之后被调用,所以你可以做一些预处理或改变结果。41/924.8DWR与Acegi整合DWR和Acegi是为了保护bean方法调用在此之前有必须熟悉spring和acegi,我就不解释acegi的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2026学年统编版八年级语文下册期末学情评估卷(含答案)
- 农业学校中餐考试题及答案
- 廉政公署考试题及答案
- 倾倒铝水安全培训课件
- 值班主任培训课件模板
- 二卷理综试卷及答案
- 企业安全环保大培训心得课件
- 小学五年级语文上册综合性学习后反思改进课件
- 小学五年级语文上册第三单元单元红色旅游介绍课件
- 深度解析(2026)《GBT 34080.2-2017基于云计算的电子政务公共平台安全规范 第2部分:信息资源安全》
- 装修公司和中介合作协议5篇
- 室内混凝土知识培训内容课件
- 2025年江苏事业单位笔试真题及答案(完整版)
- 职业卫生应急预案
- 新的生产季度安全培训课件
- 宝島台湾教学课件
- 2025年慢阻肺培训试题(附答案)
- 血细胞形态学幻灯片课件
- 铁路车务培训课件
- 海上风电场项目陆上集控中心环评报告公示
- 新专业申报答辩课件
评论
0/150
提交评论