﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-大道至简</title><link>http://www.blogjava.net/jkluooop/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 07:54:48 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 07:54:48 GMT</pubDate><ttl>60</ttl><item><title>转载:DWR提交表单</title><link>http://www.blogjava.net/jkluooop/archive/2009/04/24/267313.html</link><dc:creator>jkluooop</dc:creator><author>jkluooop</author><pubDate>Fri, 24 Apr 2009 02:58:00 GMT</pubDate><guid>http://www.blogjava.net/jkluooop/archive/2009/04/24/267313.html</guid><description><![CDATA[<h3 class="" title=""><a href="http://fqmly520.javaeye.com/blog/152383">用dwr封装表单项提交表单</a></h3>
<strong>关键字: 用dwr封装表单项提交表单</strong>
<div class="blog_content">首先,配置dwr环境，网上很多资料都说得很详细，这里就不写了。 <br />
dwr封装form表单项，需要用到dwr定义的一个js方法：DWRUtil.getValues(yourform),这个方法可以返回一个指定form中的表单项的名称和值 <br />
的map对象。 <br />
例如： <br />
&lt;form name="myform"&gt; <br />
&lt;input type="text" name="userName" id="userName"/&gt; <br />
&lt;input type="password" name="passWord" name="passWord"/&gt; <br />
&lt;/form&gt; <br />
那么DWRUtil.getValues("myform")将返回该form中的表单项的一个map对象。就不需要再写document.myform.username.value这样的语句了。 <br />
我们可以通过dwr将这个自动封装好的表单对象返传给服务器端相关方法进行操作。如果需要的话，还可以在服务器端定义好对应的formbean来接收这个表单map。 <br />
下面具体操作： <br />
1.配置好dwr运行环境。网上有很多例子，dwr所带的文档里也有说明。 <br />
2.写一个formbean来接收表单，必须有对应的set、get方法： <br />
package dwr.test; <br />
public class FormBean { <br />
private String userName; <br />
private String passWord; <br />
public String getPassWord() { <br />
&nbsp; return passWord; <br />
} <br />
public void setPassWord(String passWord) { <br />
&nbsp; this.passWord = passWord; <br />
} <br />
public String getUserName() { <br />
&nbsp; return userName; <br />
} <br />
public void setUserName(String userName) { <br />
&nbsp; this.userName = userName; <br />
} <br />
} <br />
3再写一个类来处理客户端发来的ajax请求： <br />
package dwr.test; <br />
import java.util.Map; <br />
import org.apache.commons.beanutils.BeanUtils; <br />
public class Service { <br />
public FormBean getFormBean(Map formMap){ <br />
&nbsp; FormBean formBean = new FormBean(); <br />
&nbsp; try{ <br />
&nbsp;&nbsp; BeanUtils.populate(formBean, formMap); <br />
&nbsp; }catch(Exception e){ <br />
&nbsp;&nbsp; e.printStackTrace(); <br />
&nbsp; } <br />
&nbsp; System.out.println("==============客户端传来的信息=============="); <br />
&nbsp; System.out.println("FormBean.username:"+formBean.getUserName()); <br />
&nbsp; System.out.println("FormBean.password:"+formBean.getPassWord()); <br />
&nbsp; System.out.println("========================================="); <br />
&nbsp; <br />
&nbsp; return formBean; <br />
} <br />
} <br />
其中用到的BeanUtils.populate(formBean, formMap)方法可以将formMap内的对象复制给formBean对象的属性。 <br />
BeanUtils类在struts库所带的包commons-beanutils.jar中。这样，来自客户端的表单项的值就被封装到服务器端的formBean中了，之后，操 <br />
作formBean就可以了。为了证实结果，用return formBean把封装后的表单内容返回到客户端。 <br />
4.在dwr.xml中注册相关的类及方法。 <br />
&lt;!DOCTYPE dwr PUBLIC <br />
&nbsp;&nbsp;&nbsp; "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" <br />
&nbsp;&nbsp;&nbsp; " <br />
http://www.getahead.ltd.uk/dwr/dwr10.dtd <br />
"&gt; <br />
&lt;dwr&gt; <br />
&nbsp; &lt;allow&gt; <br />
&lt;convert converter="bean" match="dwr.test.FormBean"/&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;create creator="new" javascript="Service"&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;param name="class" value="dwr.test.Service"/&gt; <br />
&nbsp; &lt;include method="getFormBean"/&gt; <br />
&lt;/create&gt;&nbsp;&nbsp; <br />
&nbsp; &lt;/allow&gt; <br />
&lt;/dwr&gt; <br />
注册FormBean是让客户端能够识别服务端返回的FormBean型数据 <br />
5.编写测试页面：test.htm <br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt; <br />
&lt;html&gt; <br />
&nbsp; &lt;head&gt; <br />
&nbsp;&nbsp; &lt;title&gt;test&lt;/title&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312" /&gt; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp; &lt;/head&gt; <br />
&nbsp;&nbsp; &lt;script src='./dwr/interface/Service.js'&gt;&lt;/script&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script src='./dwr/engine.js'&gt;&lt;/script&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script src='./dwr/util.js'&gt;&lt;/script&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script&gt; <br />
&nbsp; function formsubmit(){ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var formMap&nbsp; = DWRUtil.getValues("testform"); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert("客户端读取到的表单项：\nuserName:"+formMap["userName"]+"\npassWord:"+formMap["passWord"]); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Service.getFormBean(result,formMap); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function result(data) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br />
&nbsp;&nbsp; alert("从服务端返回的数据：\nuserName:"+data.userName+"\npassWord:"+data.userName); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
&nbsp;&nbsp;&nbsp; &lt;/script&gt; <br />
&nbsp; &lt;body&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;form name="testform"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; userName:&lt;input id="userName" name="userName" type="text"/&gt;&lt;br/&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; passWord:&lt;input id="passWord" name="passWord" type="password" /&gt;&lt;br/&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/form&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="button" value="submit" onClick="formsubmit()"/&gt; <br />
&nbsp; &lt;/body&gt; <br />
&lt;/html&gt; <br />
注意：表单中的表单项的id的大小写必须和FormBean中定义的一致 <br />
</div>
<img src ="http://www.blogjava.net/jkluooop/aggbug/267313.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jkluooop/" target="_blank">jkluooop</a> 2009-04-24 10:58 <a href="http://www.blogjava.net/jkluooop/archive/2009/04/24/267313.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载:DWR入门</title><link>http://www.blogjava.net/jkluooop/archive/2009/04/24/267306.html</link><dc:creator>jkluooop</dc:creator><author>jkluooop</author><pubDate>Fri, 24 Apr 2009 02:54:00 GMT</pubDate><guid>http://www.blogjava.net/jkluooop/archive/2009/04/24/267306.html</guid><description><![CDATA[<div class="cnt" id="blog_text">
<p><u>最近闲暇时,研究了一下DWR框架,个人感觉是一个很不错很好用的Ajax框架,封装的很好</u></p>
<p><strong>DWR入门</strong><br />
<strong>1.1 简介</strong><br />
DWR是一个可以允许你去创建AJAX WEB站点的JAVA开源库。它可以让你在浏览器中的Javascript代码调用Web服务器上的Java代码，就像在Java</p>
<p>代码就在浏览器中一样。 DWR包含2个主要部分：<br />
 一个运行在服务器端的Java Servlet，它处理请求并且向浏览器发回响应。<br />
 运行在浏览器端的JavaScript，它发送请求而且还能动态更新网页。<br />
DWR工作原理是通过动态把Java类生成为Javascript。它的代码就像Ajax魔法一样，你感觉调用就像发生在浏览器端，但是实际上代码调用发生</p>
<p>在服务器端，DWR负责数据的传递和转换。这种从Java到JavaScript的远程调用功能的方式使DWR用起来有种非常像RMI或者SOAP的常规RPC机制</p>
<p>，而且DWR的优点在于不需要任何的网页浏览器插件就能运行在网页上。 Java从根本上讲是同步机制，然而AJAX却是异步的。所以你调用远程</p>
<p>方法时，当数据已经从网络上返回的时候，你要提供有反调 （callback） 功能的DWR。<br />
<a href="http://www.java3z.com/cwbwebhome/article/article2/img4/r_howitworks.png">http://www.java3z.com/cwbwebhome/article/article2/img4/r_howitworks.png</a><br />
<strong>1.2 第一个DWR程序：Hello World</strong><br />
1.2.1 将DWR放入你的工程<br />
1） 从官方网站下载dwr.jar包。然后将它放在你webapp的WEB-INF/lib目录下。<br />
2） 将下载的dwr-版本号-src.zip \java\org\directwebremoting内的engine.js和util.js放入WEB应用中，比如js文件夹下。<br />
1.2.2 编辑配置文件<br />
1). ------------------web.xml---------------------------------------------<br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;web-app version="2.4" <br />
&nbsp;&nbsp; xmlns="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a>" <br />
&nbsp;&nbsp; xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" <br />
&nbsp;&nbsp; xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a> <br />
&nbsp;&nbsp;<a href="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd</a>"&gt;<br />
&nbsp;&nbsp; &lt;servlet&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;org.directwebremoting.servlet.DwrServlet&lt;/servlet-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;debug&lt;/param-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;true&lt;/param-value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;!-- 是servlet的加载顺序 数字越小代表加载的优先级越高 --&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />
&nbsp;&nbsp; &lt;/servlet&gt;</p>
<p>&nbsp;&nbsp; &lt;servlet-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/dwr/*&lt;/url-pattern&gt;<br />
&nbsp;&nbsp; &lt;/servlet-mapping&gt;<br />
<br />
<br />
&nbsp;&nbsp; &lt;welcome-file-list&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br />
&nbsp;&nbsp; &lt;/welcome-file-list&gt;<br />
&lt;/web-app&gt;<br />
2).--------------------------dwr.xml----------------------------------------------<br />
在web.xml的同一目录下，创建dwr.xml，<br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "<a href="http://getahead.org/dwr/dwr20.dtd">http://getahead.org/dwr/dwr20.dtd</a>"&gt;</p>
<p>&lt;dwr&gt;</p>
<p>&nbsp;&nbsp; &lt;allow&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;create creator="new" javascript="service"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="class" value="helloWorld.Service"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/create&gt;</p>
<p>&nbsp;&nbsp; &lt;/allow&gt;</p>
<p>&lt;/dwr&gt;<br />
3)。 编写---------------------------service.java--------------------------------<br />
就像没有dwr一样，写一个简单类并加一个方法 是 <br />
package helloWorld; <br />
public class Service <br />
{ public String sayHello(String yourName) <br />
{ //可以是访问数据库的复杂代码 <br />
return "Hello World " + yourName; <br />
} <br />
}<br />
4)。 -----------------------------------测试DWR-------------------------------------<br />
将代码放入应用服务器（比如Tomcat），启动。<br />
然后在地址栏输入<a href="http://localhost:8080/">http://localhost:8080/</a>你的工程/dwr 然后点击service，会看到刚才写的sayHello()的方法，输入自己的名字然</p>
<p>后点击&#8220;Execute&#8221;，如果发现确实是正确的返回结果，说明测试通过了，可以进入下一步了。<br />
5)。--------------------------------- 编写一个 index.jsp---------------------------------<br />
&lt;%@ page language="java" pageEncoding="UTF-8"%&gt;<br />
&lt;html&gt;<br />
&nbsp;&nbsp; &lt;head&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;title&gt;My JSP 'first_dwr.jsp' starting page&lt;/title&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;script type='text/javascript' src="js/util.js"&gt;&lt;/script&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;script type='text/javascript' src="js/engine.js"&gt;&lt;/script&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;script type='text/javascript' src="js/service.js"&gt; &lt;/script&gt;<br />
&lt;script type="text/javascript"&gt; <br />
&nbsp;&nbsp; function firstDwr()<br />
&nbsp;&nbsp; { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.sayHello("孤魂",callBackHello);<br />
&nbsp;&nbsp; }<br />
&nbsp;&nbsp; function callBackHello(data){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert(data); <br />
&nbsp;&nbsp;&nbsp; }<br />
&lt;/script&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt; <br />
&lt;input type="button" name="button" value="测试" onclick="firstDwr()"&gt; <br />
&lt;/body&gt; <br />
&lt;/html&gt;</p>
<p><strong>2.2 常用&lt;init-param&gt;参数列表(web.xml中的)</strong></p>
<p><strong>2.2.1 安全参数</strong><br />
allowGetForSafariButMakeForgeryEasier <br />
开始版本：2.0 <br />
默认值：false <br />
描述：置成true使DWR工作在Safari 1.x , 会稍微降低安全性。<br />
crossDomainSessionSecurity <br />
开始版本：2.0 <br />
默认值：true<br />
描述：设置成false使能够从其他域进行请求。注意，这样做会在安全性上有点冒险，参考一下这篇文章，在没有理解这个后果前不要设置成为false。<br />
debug <br />
开始版本：1.0 <br />
默认值：false <br />
描述：设置成true使DWR能够debug和进入测试页面 <br />
scriptSessionTimeout <br />
开始版本：2.0 <br />
默认值：1800000(30分钟) <br />
描述：script session 的超时设置 <br />
maxCallCount <br />
开始版本：2.0rc2 和 1.1.4 <br />
默认值：20 <br />
描述：一次批量(batch)允许最大的调用数量。(帮助保护Dos攻击)<br />
<strong>2.2.2 Ajax服务器加载时保护参数</strong><br />
pollAndCometEnabled <br />
开始版本：2.0<br />
默认值：false <br />
描述：设置成true能增加服务器的加载能力，尽管DWR有保护服务器过载的机制。<br />
maxWaitingThreads <br />
开始版本：2.0 <br />
默认值：100 <br />
描述：最大等待线程数量。 <br />
preStreamWaitTime <br />
开始版本：2.0 <br />
默认值：29000(单位：毫秒) <br />
描述：对一个打开流前的反应，等待的最大时间 <br />
postStreamWaitTime <br />
开始版本：2.0 <br />
默认值：1000(单位：毫秒) <br />
描述：对一个打开流后的反应，等待的最大时间<br />
<br />
<strong>2.3 日志配置</strong><br />
DWR工作在JDK1.3中不支持java.util.logging，但我们并不强迫任何人都去使用commons-logging或者log4j，所以在使用HttpServlet.log()方法时DWR将正常工作，如果没有日志类的话。然而如果DWR可以使用，那么它将使用日志。<br />
<em><strong>Commoms-Logging</strong> <br />
</em>由于大多数servlet容器都使用它，几乎每个人都将使用commons-logging。所以如果你的webapp不明确使用commons-logging，它将被默认设为可以使用。 在这些日志将被一些配置文件所约束，比如java.util.logging或者log4j，可以去查看他们各自的文档获得详情。<br />
<strong><em>HttpServlet.log()</em></strong> <br />
如果你正在使用HttpServlet.log()， 以下的代码用来控制DWR日志<br />
&lt;init-param&gt; <br />
&lt;param-name&gt;logLevel&lt;/param-name&gt; <br />
&lt;param-value&gt;DEBUG&lt;/param-value&gt; <br />
&lt;/init-param&gt;<br />
值可以是：FATAL，ERROR，WARN(默认)，INFO，DEBUG</p>
<p><br />
<strong>DWR2.0插件<br />
</strong> org.directwebremoting.Container<br />
 org.directwebremoting.WebContextFactory.WebContextBuilder<br />
 org.directwebremoting.ServerContextFactory.ServerContextBuilder<br />
 org.directwebremoting.servlet.UrlProcessor<br />
 org.directwebremoting.extend.AccessControl<br />
 org.directwebremoting.extend.AjaxFilterManager<br />
 org.directwebremoting.extend.ConverterManager<br />
 org.directwebremoting.extend.CreatorManager<br />
 org.directwebremoting.extend.DebugPageGenerator<br />
 org.directwebremoting.extend.HtmlCallMarshaller<br />
 org.directwebremoting.extend.HtmlPollHandler<br />
 org.directwebremoting.extend.PageNormalizer<br />
 org.directwebremoting.extend.PlainCallMarshaller<br />
 org.directwebremoting.extend.PlainPollHandler<br />
 org.directwebremoting.extend.Remoter<br />
 org.directwebremoting.extend.ScriptSessionManager<br />
 org.directwebremoting.extend.ServerLoadMonitor</p>
<p><strong>--------------------------------------------------------dwr.xml配置----------------------------------------------</strong></p>
<p>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "<a href="http://www.getahead.ltd.uk/dwr/dwr20.dtd">http://www.getahead.ltd.uk/dwr/dwr20.dtd</a>"&gt;<br />
&lt;dwr&gt;<br />
&lt;!-- 仅当需要扩展DWR时才需要 --&gt;<br />
&lt;init&gt;<br />
&nbsp;&nbsp; &lt;creator id="..." class="..." /&gt;<br />
&nbsp;&nbsp; &lt;converter id="..." class="..." /&gt;<br />
&lt;/init&gt;&lt;!-- 没有它DWR什么也做不了 --&gt;<br />
&lt;allow&gt;<br />
&nbsp;&nbsp; &lt;create creator="..." javascript="..." /&gt;<br />
&nbsp;&nbsp; &lt;convert converter="..." match="..." /&gt;<br />
&lt;/allow&gt;&lt;!-- 有必要告诉DWR方法签名 --&gt;<br />
&lt;signatures&gt;...&lt;/signatures&gt;<br />
&lt;/dwr&gt;</p>
<p><strong>3.2 &lt;init&gt;标签</strong><br />
这个初始化部分申明被用来创建远程beans而且这个类能被用来以某种过程转换。大多数例子你将不需要用它，如果你想去定义一个新的Creator或者Converter，就要在此被申明。 在init部分里有了定义只是告诉DWR这些扩展类的存在，给出了如何使用的信息。这时他们还没有被使用。这种方式很像Java中的import语句。多数类需要在使用前先import一下，但是只有import语句并不表明这个类已经被使用了。每一个creator和converter都用id属性，以便后面使用。</p>
<p><strong>3.3 &lt;allow&gt;标签</strong><br />
allow部分定义了DWR能够创建和转换的类。<br />
<strong><em>3.3.1 Creator</em></strong><br />
每一个在类中被调用的方法需要一个&lt;create &#8230;&gt;有若干类型的creator，使用&#8220;new&#8221;关键字或者Spring 框架等。</p>
<p>create元素是如下的结构：</p>
<p>&lt;allow&gt;<br />
&lt;create creator="..." javascript="..." scope="..."&gt;<br />
&nbsp;&nbsp; &lt;param name="..." value="..." /&gt;<br />
&nbsp;&nbsp; &lt;auth method="..." role="..." /&gt;<br />
&nbsp;&nbsp; &lt;exclude method="..." /&gt;<br />
&nbsp;&nbsp; &lt;include method="..." /&gt;<br />
&lt;/create&gt;<br />
...<br />
&lt;/allow&gt;</p>
<p><strong><em>1)．new：Java用&#8220;new&#8221;关键字创造对象 是DWR默认的creator，如下所示 &lt;create id="new"</em></strong> class="org.directwebremoting.create.NewCreator"/&gt;<br />
没有必要把它加入dwr.xml，它已经在DWR内部文件了。 这个creator将使用默认构造器创建类的实例，以下是用new创建器的好处<br />
 安全:DWR创造的对象生存的时间越短，多次调用中间的值不一致的错误机会越少。<br />
 内存消耗低： 如果你的站点用户量非常大，这个创造器可以减少VM的内存溢出。<br />
<strong><em>2)．none: 它不创建对象，看下面的原因。</em></strong></p>
<p>(v1.1+) none创建器不创建任何对象，它会假设你不须要创建对象。有2个使用的原因：<br />
 你可能在使用的scope不是"page"(看上面)，并在在前面已经把这个对象创建到这个scope中了，这时你就不需要再创建对象了。<br />
 还有一种情况是要调用的方法是静态的，这时也不需要创建对象。DWR会在调用创建器之前先检查一下这个方法是不是静态的。</p>
<p><strong>2. javascript属性</strong><br />
在浏览器里给你创建的对象命名。避免使用JavaScript保留字。这个名字将在页面里作为js被导入，就像第2章节的那个jsp： dwr.xml</p>
<p>&lt;create creator="new" javascript="service"&gt;</p>
<p>&nbsp;&nbsp; &lt;param name="class" value="helloWorld.Service" /&gt;</p>
<p>&lt;/create&gt;<br />
<strong><em>html / jsp：</em></strong></p>
<p>&lt;html&gt; &lt;head&gt; </p>
<p>&#8230;</p>
<p>&lt;script type='text/javascript' src='dwr/interface/service.js'&gt;</p>
<p>&#8230;</p>
<p><strong>3. scope属性<br />
</strong>和定义在servlet的scope一样大的范围，它允许你指定哪个bean是可以获得的。选项可以是：application, session, request和page。这些值应该已经被开发者们熟悉了。</p>
<p><strong>4. param元素</strong><br />
被用来指定创造器的其他参数，每种构造器各有不同。例如，"new"创造器需要知道要创建的对象类型是什么。每一个创造器的参数在各自的文档中能找到。<br />
<strong>5. include和exclude元素</strong><br />
允许一个创造器去限制进入类的方法。一个创造器必须指定include列表或exclude列表之一。如果是include列表则暗示默认的访问策略是"拒绝"，include中的每个方法就是允许访问的方法；如果是exclude列表则暗示默认的访问策略是"允许"，exclude中的每个方法就是拒绝访问的方法。 比如：</p>
<p>&lt;create creator="new" javascript="Fred"&gt;<br />
&nbsp;&nbsp; &lt;param name="class" value="com.example.Fred" /&gt; <br />
&nbsp;&nbsp; &lt;include method="setWibble" /&gt; <br />
&lt;/create&gt;</p>
<p><br />
<strong>3.3.2 Converter<br />
</strong>我们需要确认所有的参数能被转换。许多JDK提供的类型使你能够使用，但是你如果要转换你自己的代码，就必须告诉DWR。一般是指JavaBean的参数需要一个&lt;convert&#8230;&gt;标签作为入口。</p>
<p>你不需要在dwr.xml中&lt;allow&gt;部分的&lt;convert&gt;中定义。它们默认支持。<br />
 所有主要的类型，boolean, int , double等等。<br />
 包装类，Boolean, Integer等等。<br />
 java.lang.String<br />
 java.util.Date 和 java.sql.Times，java.sql.Timestamp。<br />
 数组(存放以上类型的)<br />
 集合类型 (List, Set, Map, Iterator等等) (存放以上类型的)<br />
 DOM对象(来自于DOM, XOM, JDOM和DOM4J)</p>
<p><strong>1. 日期转换器</strong><br />
如果你有一个String(例如：&#8220;2001－02－11&#8221;)在Javascript，你想把它转换成Java日期。那么你有2种选择，一是使用Date.parse()然后使用DataConverter传入服务器端，还有一种选择是把该String传入，然后用java的SimpleDateFormat(或者其他的)来转换。 同样，如果你有个Java的Date类型并且希望在HTML使用它。你可以先用SimpleDateFormat把它转换成字符串再使用。也可以直接传Date给Javascript，然后用Javascript格式化。第一种方式简单一些，尽管浪费了你的转换器，而且这样做也会是浏览器上的显示逻辑受到限制。其实后面的方法更好，也有一些工具可以帮你</p>
<p><strong>2. 数组转换器</strong><br />
数组实体不太容易理解。默认情况下DWR能转换所有原生类型的数组，还有所有marshallable对象的数组。这些marshallable对象包括前面介绍的String和Date类型。match属性看上去很怪。<br />
<strong>3. bean和对象转换器</strong><br />
两个没有默认打开的转换器是Bean 和 Object 转换器。Bean转换器可以把POJO转换成Javascript的接合数组(类似与Java中的Map)，或者反向转换。这个转换器默认情况下是没打开的，因为DWR要获得你的允许才能动你的代码。 Object转换器很相似，不同的是它直接应用于对象的成员，而不是通过getter和setter方法。下面的例子都是可以用object来替换bean的来直接访问对象成员。 如果你有一个在 &lt;create ...&gt; 中声明的远程调用Bean。它有个一参数也是一个bean，并且这个bean有一个setter存在一些安全隐患，那么攻击者就可能利用这一点。 你可以为某一个单独的类打开转换器：</p>
<p>&lt;convert converter="bean" match="your.full.package.BeanName"/&gt;<br />
如果要允许转换一个包或者子包下面的所有类，可以这样写： &lt;convert converter="bean" match="your.full.package.*"/&gt;<br />
显而易见，这样写是允许转换所有的JavaBean： &lt;convert converter="bean" match="*"/&gt;<br />
 BeanConverter 和 JavaBeans 规范 用于被BeanConverter转换的Bean必须符合JavaBeans的规范，因为转换器用的是Introspection，而不是Reflection。</p>
<p>这就是说属性要符合一下条件：有getter和setter，setter有一个参数，并且这个参数的类型是getter的返回类型。setter应该返回void，getter应该没有任何参数。setter没有重载。以上这些属于常识。就在eclipse里自动为每个属性添加setter，getter那种类型，如果你用的不是JavaBean，那么你应该用ObjectConverter.<br />
 设置Javascript变量 DWR可以把Javascript对象(又名maps，或联合数组)转换成JavaBean或者Java对象。例子：<br />
public class Remoted {</p>
<p>public void setPerson(Person p) { // ... } }</p>
<p>public class Person {</p>
<p>&nbsp;&nbsp;&nbsp; public void setName(String name) { ... }</p>
<p>public void setAge(int age) { ... } // ... }</p>
<p>如果这个Remoted已经被配置成Creator了，Persion类也定义了BeanConverter，那么你可以通过下面的方式调用Java代码：</p>
<p>var p = { name:"Fred", age:21 }; Remoted.setPerson(p);</p>
<p><strong>4. 集合类型转换器</strong><br />
有个两个默认的转换器，针对Map和Collection：</p>
<p>&lt;convert converter="collection" match="java.util.Collection"/&gt;</p>
<p>&lt;convert converter="map" match="java.util.Map"/&gt;</p>
<p><strong>4.7 DWR与WebWork</strong><br />
WebWork支持在DWR2.0m3以后才有。 要可以通过DWR调用WW的Action，要做两件事。<br />
<strong>4.7.1 配置dwr.xml</strong><br />
你必须在dwr的配置文件中加入这样的配置：</p>
<p>&lt;create creator="none" javascript="DWRAction"&gt;<br />
&lt;param name="class" value="org.directwebremoting.webwork.DWRAction" /&gt;<br />
&lt;include method="execute" /&gt;<br />
&lt;/create&gt;<br />
&lt;convert converter="bean"<br />
match="org.directwebremoting.webwork.ActionDefinition"&gt;<br />
&lt;param name="include" value="namespace,action,method,executeResult" /&gt;<br />
&lt;/convert&gt;<br />
&lt;convert converter="bean"<br />
match="org.directwebremoting.webwork.AjaxResult" /&gt;<br />
&lt;convert converter="bean" match="your_action_package.*"/&gt;</p>
<p>这样你AjaxWebWork Action调用返回一个action实例(而不是文字)。然后你必须包括action对象的转换<br />
器定义(package级别或单独action)。</p>
<p><strong>------------------------------------------DWR中的JavaScript简介---------------------------------------------</strong></p>
<p>DWR根据dwr.xml生成和Java代码类似的Javascript代码。 相对而言Java同步调用，创建与Java代码匹配的Ajax远程调用接口的最大挑战来至与实现Ajax的异步调用特性。</p>
<p><strong>5.1 简单的回调函数</strong></p>
<p>假设你有一个这样的Java方法：<br />
public class Remote { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getData(int index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { ... } <br />
}</p>
<p>&lt;script type='text/javascript' src='[WEBAPP]/dwr/engine.js'&gt;&lt;/script&gt;<br />
&lt;script type='text/javascript' src='[WEBAPP]/dwr/interface/Remote.js'&gt;&lt;/script&gt;<br />
&#8230;&#8230;<br />
&lt;script type="text/javascript"&gt;<br />
function handleGetData(str) { alert(str); } Remote.getData(42,<br />
handleGetData);<br />
&lt;/script&gt;</p>
<p><strong><em>42是Java方法getData()的一个参数。</em></strong></p>
<p>此外你也可以使用这种减缩格式： Remote.getData(42, function(str) { alert(str); });</p>
<p>5.2 调用元数据对象<br />
另外一种语法时使用"调用元数据对象"来指定回调函数和其他的选项。上面的例子可以写成这样：</p>
<p>Remote.getData(42, {</p>
<p>&nbsp;&nbsp; callback:function(str) { alert(str);</p>
<p>} });</p>
<p><strong>---------------------------------------------------- util.js 功能-----------------------------------------------------</strong><br />
util.js包含了一些工具函数来帮助你用javascript数据(例如从服务器返回的数据)来更新你的web页面。 你可以在DWR以外使用它，因为它不依赖于DWR的其他部分。你可以下载整个DWR或者单独下载. 4个基本的操作页面的函数：getValue[s]()和setValue[s]()可以操作大部分HTML元素除了table，list和image。getText()可以操作select list。 要修改table可以用addRows()和removeAllRows()。要修改列表(select列表和ul,ol列表)可以用addOptions()和removeAllOptions()。 还有一些其他功能不是DWRUtil的一部分。但它们也很有用，它们可以用来解决一些小问题，但是它们不是对于所有任都通用的。<br />
<strong>7.1 $()</strong><br />
$() 函数(它是合法的Javascript名字) 是从Protoype偷来的主意。 大略上的讲： $ = document.getElementById。 因为在Ajax程序中，你会需要写很多这样的语句，所以使用 $() 会更简洁。 通过指定的id来查找当前HTML文档中的元素，如果传递给它多个参数，它会返回找到的元素的数组。所有非String类型的参数会被原封不动的返回。这个函数的灵感来至于prototype库，但是它可以在更多的浏览器上运行。 可以看看DWRUtil.toDescriptiveString的演示。 从技术角度来讲他在IE5.0中是不能使用的，因为它使用了Array.push，尽管如此通常它只是用来同engine.js一起工作。如果你不想要engine.js并且在IE5.0中使用，那么你最好为Array.push找个替代品。<br />
<strong>7.2 addOptions and removeAllOptions</strong><br />
DWR的一个常遇到的任务就是根据选项填充选择列表。下面的例子就是根据输入填充列表。 下面将介绍 DWRUtil.addOptions() 的几种是用方法。 如果你希望在你更新了select以后，它仍然保持运来的选择，你要像下面这样做： var sel = DWRUtil.getValue(id); DWRUtil.removeAllOptions(id); DWRUtil.addOptions(id, ...); DWRUtil.setValue(id, sel);<br />
55 / 92<br />
如果你想加入一个初始的"Please select..." 选项那么你可以直接加入下面的语句： DWRUtil.addOptions(id, \["Please select ..."]);<br />
DWRUtil.addOptions有5种模式<br />
 数组: DWRUtil.addOptions(selectid, array) 会创建一堆option，每个option的文字和值都是数组元素中的值。<br />
 对象数组 (指定text): DWRUtil.addOptions(selectid, data, prop) 用每个数组元素创造一个option，option的值和文字都是在prop中指定的对象的属性。<br />
 对象数组 (指定text和value值): DWRUtil.addOptions(selectid, array, valueprop, textprop) 用每个数组元素创造一个option，option的值是对象的valueprop属性，option的文字是对象的textprop属性。<br />
 对象: DWRUtil.addOptions(selectid, map, reverse)用每个属性创建一个option。对象属性名用来作为option的值，对象属性值用来作为属性的文字，这听上去有些不对。但是事实上却是正确的方式。如果reverse参数被设置为true，那么对象属性值用来作为选项的值。<br />
 对象的Map: DWRUtil.addOptions(selectid, map, valueprop, textprop) 用map中的每一个对象创建一个option。用对象的valueprop属性做为option的value，用对象的textprop属性做为option的文字。<br />
 ol 或 ul 列表: DWRUtil.addOptions(ulid, array) 用数组中的元素创建一堆li元素，他们的innerHTML是数组元素中的值。这种模式可以用来创建ul和ol列表。<br />
这是网上的例子</p>
<p><strong>7.3 addRows and removeAllRows</strong><br />
DWR通过这两个函数来帮你操作table： DWRUtil.addRows() 和 DWRUtil.removeAllRows() 。这个函数的第一个参数都是table、tbody、thead、tfoot的id。一般来说最好使用tbody，因为这样可以保持你的header和footer行不变，并且可以防止Internet Explorer的bug。<br />
 DWRUtil.removeAllRows()<br />
DWRUtil.removeAllRows(id);<br />
描述: 通过id删除table中所有行。 参数: id： table元素的id(最好是tbody元素的id)</p>
<p> DWRUtil.addRows()<br />
DWRUtil.addRows(id, array, cellfuncs, [options]);<br />
描述: 向指定id的table元素添加行。它使用数组中的每一个元素在table中创建一行。然后用cellfuncs数组中的没有函数创建一个列。单元格是依次用cellfunc根据没有数组中的元素创建出来的。 DWR1.1开始，addRows()也可以用对象做为数据。如果你用一个对象代替一个数组来创建单元格，这个对象会被传递给cell函数。 参数: id: table元素的id(最好是tbody元素的id) array: 数组(DWR1.1以后可以是对象)，做为更新表格数据。 cellfuncs: 函数数组，从传递过来的行数据中提取单元格数据。 options: 一个包含选项的对象(见下面) 选项包括: rowCreator: 一个用来创建行的函数(例如，你希望个tr加个css). 默认是返回一个document.createElement("tr") cellCreator: 一个用来创建单元格的函数(例如，用th代替td). 默认返回一个document.createElement("td")<br />
这是网上的例子<br />
<strong>7.4 getText</strong><br />
getText(id)和getValue(id)很相似。出了它是为select列表设计的。你可能需要取得显示的文字，而不是当前选项的值。<br />
这是网上的例子<br />
7.5 getValue<br />
DWRUtil.getValue(id)是 setValue()对应的"读版本"。它可以从HTML元素中取出其中的值，而你不用管这个元素是select列表还是一个div。 这个函数能操作大多数HTML元素包括select(去处当前选项的值而不是文字)、input元素(包括textarea)、div和span。<br />
这是网上的例子</p>
<p><strong>7.6 getValues</strong><br />
getValues()和getValue()非常相似，除了输入的是包含name/value对的javascript对象。name是HTML元素的ID，value会被更改为这些ID对象元素的内容。这个函数不会返回对象，它只更改传递给它的值。 从DWR1.1开始getValues()可以传入一个HTML元素(一个DOM对象或者id字符串)，然后从它生成一个reply对象。<br />
<strong><br />
7.7 onReturn</strong><br />
当按下return键时，得到通知。 当表单中有input元素，触发return键会导致表单被提交。当使用Ajax时，这往往不是你想要的。而通常你需要的触发一些Javscript。 不幸的是不同的浏览器处理这个事件的方式不一样。所以DWRUtil.onReturn修复了这个差异。如果你需要一个同表单元素中按回车相同的特性，你可以用这样代码实现： &lt;input type="text" onkeypress="DWRUtil.onReturn(event,submitFunction)"/&gt; &lt;input type="button" onclick="submitFunction()"/&gt;<br />
你也可以使用onkeypress事件或者onkeydown事件，他们做同样的事情。 一般来说DWR不是一个Javascript类库，所以它应该试图满足这个需求。不管怎样，这是在使用Ajax过程中一个很有用函数。 这个函数的工作原理是onSubmit()事件只存在于&lt;FORM ...&gt;元素上<br />
这是网上的例子<br />
7.8 selectRange<br />
选择一个输入框中的一定范围的文字。 你可能为了实现类似"Google suggest"类型的功能而需要选择输入框中的一定范围的文字，但是不同浏览器间选择的模型不一样。这DWRUtil函数可以帮你实现。 DWRUtil.selectRange(ele, start, end)<br />
这是网上的例子</p>
<p><strong>7.9 setValue<br />
</strong>DWRUtil.setValue(id, value)根据第一个参数中指定的id找到相应元素，并根据第二个参数改变其中的值。 这个函数能操作大多数HTML元素包括select(去处当前选项的值而不是文字)、input元素(包括textarea)、div和span。<br />
这是网上的例子<br />
<strong>7.10 setValues</strong><br />
setValues()和setValue()非常相似，除了输入的是包含name/value对的javascript对象。name是HTML元素的ID，value是你想要设置给相应的元素的值。<br />
这是网上的例子<br />
<strong>7.11 toDescriptiveString</strong><br />
DWRUtil.toDescriptiveString()函数比默认的toString()更好。第一个参数是要调试的对象，第二个参数是可选的，用来指定内容深入的层次： 0: 单行调试 1: 多行调试，但不深入到子对象。 2: 多行调试，深入到第二层子对象 以此类推。一般调试到第二级是最佳的。 还有第三个参数，定义初始缩进。这个函数不应该被用于调式程序之外，因为以后可能会有变化。<br />
这是网上的例子<br />
<strong>7.12 useLoadingMessage</strong><br />
这个方法将来可能被废弃，因为这个实现实在太专断了。为什么是红色，为什么在右上角，等等。唯一的真正答案就是：抄袭GMail。这里的建议是以本页面中的代码为模板，根据你的需求自定义。 你必须在页面加载以后调用这个方法(例如，不要在onload()事件触发之前调用)，因为它要创建一个隐藏的div来容纳消息。</p>
<p>最简单的做法时在onload事件中调用DWRUtil.useLoadingMessage，像这样： &lt;head&gt; &lt;script&gt; function init() { DWRUtil.useLoadingMessage(); } &lt;/script&gt; ... &lt;/head&gt; &lt;body onload="init();"&gt; ...<br />
可能有些情况下你是不能容易的编辑header和body标签(如果你在使用CMS，这很正常)，在这样的情况下你可以这样做： &lt;script&gt; function init() { DWRUtil.useLoadingMessage(); } if (window.addEventListener) { window.addEventListener("load", init, false); } else if (window.attachEvent) { window.attachEvent("onload", init); } else { window.onload = init; } &lt;/script&gt;<br />
下面这些是这个函数的代码，它对于你要实现自己的加载消息很有用。这个函数的主要内容是动态创建一个div(id是disabledZone)来容纳消息。重要的代码是当远程调用时使它显示和隐藏： DWREngine.setPreHook(function() { $('disabledZone').style.visibility = 'visible'; }); DWREngine.setPostHook(function() { $('disabledZone').style.visibility = 'hidden'; }); This is fairly simple and makes it quite easy to implement your own "loading" message.</p>
<p>function useLoadingImage(imageSrc) { var loadingImage; if (imageSrc) loadingImage = imageSrc; else loadingImage = "ajax-loader.gif"; DWREngine.setPreHook(function() { var disabledImageZone = $('disabledImageZone'); if (!disabledImageZone) { disabledImageZone = document.createElement('div'); disabledImageZone.setAttribute('id', 'disabledImageZone'); disabledImageZone.style.position = "absolute"; disabledImageZone.style.zIndex = "1000"; disabledImageZone.style.left = "0px"; disabledImageZone.style.top = "0px"; disabledImageZone.style.width = "100%"; disabledImageZone.style.height = "100%"; var imageZone = document.createElement('img'); imageZone.setAttribute('id','imageZone'); imageZone.setAttribute('src',imageSrc); imageZone.style.position = "absolute"; imageZone.style.top = "0px"; imageZone.style.right = "0px"; disabledImageZone.appendChild(imageZone); document.body.appendChild(disabledImageZone); } else { $('imageZone').src = imageSrc; disabledImageZone.style.visibility = 'visible'; } }); DWREngine.setPostHook(function() { $('disabledImageZone').style.visibility = 'hidden'; }); }<br />
然后你就可以这样使用:useLoadingImage("images/loader.gif");</p>
<p><strong>7.13 Submission box</strong><br />
h1 非util.js中的功能 这里有一些功能不适合加入到DWRUtil中。它们在解决一下特殊问题是很有用，但是他们还不够通用以适用任何场合。<br />
62 / 92<br />
修补浏览器事件 如果你创建了一个DOM元素，然后用addAttribute在这个元素上创建了一个事件，那么他们不能被正常的触发。你可以使用下面的脚本来遍历一个DOM树，并重新为他们绑定事件，这样他们就能正常的触发了。 把'click'改成你希望的事件。 DWREngine._fixExplorerEvents = function(obj) { for (var i = 0; i &lt; obj.childNodes.length; i++) { var childObj = obj.childNodes [i]; if (childObj.nodeValue == null) { var onclickHandler = childObj.getAttribute('onclick'); if (onclickHandler != null) { childObj.removeAttribute('onclick'); // If using prototype: // Event.observe(childObj, 'click', new Function(onclickHandler)); // Otherwise (but watch out for memory leaks): if (element.attachEvent) { element.attachEvent("onclick", onclickHandler); } else { element.addEventListener("click", onclickHandler, useCapture); } } DWREngine._fixExplorerEvents(childObj); } }</p>
<p><strong>8.5 安全</strong><br />
我们很谨慎的对待DWR的安全问题，并且认为有必要解释一下避免错误要做的事情。 首先DWR让你明确哪些是被远程调用的，是如何被远程调用。原则就是DWR必须调用那些你明确允许的代码。 dwr.xml要求你为每一个远程类定义一个'create'项。你还可以通过指定include和exclude元素来更精确的控制远程调用Bean中可以被调用的方法。 除此之外如果你希望允许DWR在转换你的JavaBean到Javascript或者从Javascript转换到JavaBean时有一定的许可限制，同样可以精确控制哪些Bean的属性可以被转换。 一个很明显但又必须指出的 &#8211; 不要在生产环境中打开test/debug模式控制台。如何打开或关闭debug控制台在配置web.xml部分可以找到详细描述。<br />
 审查 - DWR带来的最大好处<br />
很值得对比一下DWR和Servlet、JSP或周围的其他web框架。 如果你要审查基于DWR的功能，那是非常简单的。看看dwr.xml你就能得到一个哪些方法被暴露到外面的描述了。你也可以俯视全局用DWR可以访问哪些资源。 但是要在其他系统里做这件事可不是这么容易。如果是Servlet你需要检查WEB-INF/web.xml文件，然后检查写在Servlet中的request.getParameter(...)。如果是Struts和其他Framework你需要检查配置文件，然后顺着流程检查代码，看请求信息出了什么问题。<br />
 访问控制<br />
DWR允许你通过两种基于J2EE的机制来进行访问控制。首先你可以基于J2EE角色定义DWR的访问。其次你可以在DWR里面定义访问方法的角色。<br />
 其他方面<br />
DWR不允许你定义任何内部类的create和convert。这样设计是为了不出现意外的攻击来操作DWR的核心文件以提升访问权限。<br />
 风险<br />
有什么机会可以让攻击者窥视你的系统呢？使用DWR你攻击者可以使服务器创建任何你在dwr.xml中指定的Java对象的实例。并且(如果你用BeanConverter)Java类的任何方法、以及方法任何参数都是可见的。这些类的任何一个属性都有可能是攻击者需要的。 如果你知道DWR是怎么工作的，这些都是很显而易见的结论，但是往往粗心会造成问题。如果你创建了一个有appendStringToFile()方法的FileBean的类，而且用DWR把它暴露出去，那么你就给了攻击者一个机会来填满你的文件系统。<br />
69 / 92<br />
你必须时刻注意用了DWR以后，有没有给攻击者什么机会。 一般来说这样的情景让人感觉使用DWR是有风险的，但是这样的问题在所有的传统web架构中都存在，只是在那些架构中这些不明显，所以就很难被修复。<br />
 保证更加安全<br />
这已经很安全了，那么你还能做什么来保证更加安全了？首先记住上面这些关于审查的内容，当web应用的其他地方不安全时，即使它看上去很安全，过多的关注DWR是很愚蠢的。如果DWR让人感觉恐惧，那是因为它的问题都在明处。所以第一步是多检查几遍传统架构的问题。 你可以通过把可远程访问的类放到不同的包里，并且使用代理来防止DWR访问机制出问题。如果你愿意还可以再次检查基于角色的安全控制。这些内容只是在检查DWR已经为你做的事情。 比多检查几次更好的方法是检查DWR的源码，保证它是在正确的工作。这些代码已经被很多人检查过了，但多双眼睛总是有好处的。<br />
 整合Acegi<br />
DWR可以整合Acegi security framework。更多的信息见整合DWR和Acegi.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>完结。。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
</div>
<img src ="http://www.blogjava.net/jkluooop/aggbug/267306.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jkluooop/" target="_blank">jkluooop</a> 2009-04-24 10:54 <a href="http://www.blogjava.net/jkluooop/archive/2009/04/24/267306.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java各种对象理解</title><link>http://www.blogjava.net/jkluooop/archive/2009/04/24/267302.html</link><dc:creator>jkluooop</dc:creator><author>jkluooop</author><pubDate>Fri, 24 Apr 2009 02:50:00 GMT</pubDate><guid>http://www.blogjava.net/jkluooop/archive/2009/04/24/267302.html</guid><description><![CDATA[<p><font color="#333333" size="2">关于VO、PO的理解-java的(PO,VO,TO,BO,DAO,POJO)解释收藏</font></p>
<p><font color="#333333" size="2">O/R Mapping 是 Object Relational Mapping（对象关系映射）的缩写。通俗点讲，就是将对象与关系数据库绑定，用对象来表示关系数据。在O/R Mapping的世界里，有两个基本的也是重要的东东需要了解，即VO，PO。<br />
　　VO，值对象(Value Object)，PO，持久对象(Persisent Object)，它们是由一组属性和属性的get和set方法组成。从结构上看，它们并没有什么不同的地方。但从其意义和本质上来看是完全不同的。</font></p>
<p><font color="#333333" size="2">１．VO是用new关键字创建，由GC回收的。 <br />
　　PO则是向数据库中添加新数据时创建，删除数据库中数据时削除的。并且它只能存活在一个数据库连接中，断开连接即被销毁。 </font></p>
<p><font color="#333333" size="2">２．VO是值对象，精确点讲它是业务对象，是存活在业务层的，是业务逻辑使用的，它存活的目的就是为数据提供一个生存的地方。 <br />
　　PO则是有状态的，每个属性代表其当前的状态。它是物理数据的对象表示。使用它，可以使我们的程序与物理数据解耦，并且可以简化对象数据与物理数据之间的转换。</font></p>
<p><font color="#333333" size="2">３．VO的属性是根据当前业务的不同而不同的，也就是说，它的每一个属性都一一对应当前业务逻辑所需要的数据的名称。 <br />
　　PO的属性是跟数据库表的字段一一对应的。</font></p>
<p><font color="#333333" size="2">PO对象需要实现序列化接口。<br />
-------------------------------------------------</font></p>
<p><font color="#333333" size="2"><font color="#333399">PO是持久化对象，它只是将物理数据实体的一种对象表示，为什么需要它？因为它可以简化我们对于物理实体的了解和耦合，简单地讲，可以简化对象的数据转换为物理数据的编程。VO是什么？它是值对象，准确地讲，它是业务对象，是生活在业务层的，是业务逻辑需要了解，需要使用的，再简单地讲，它是概念模型转换得到的。 <br />
首先说PO和VO吧，它们的关系应该是相互独立的，一个VO可以只是PO的部分，也可以是多个PO构成，同样也可以等同于一个PO（当然我是指他们的属性）。正因为这样，PO独立出来，数据持久层也就独立出来了，它不会受到任何业务的干涉。又正因为这样，业务逻辑层也独立开来，它不会受到数据持久层的影响，业务层关心的只是业务逻辑的处理，至于怎么存怎么读交给别人吧！不过，另外一点，如果我们没有使用数据持久层，或者说没有使用hibernate，那么PO和VO也可以是同一个东西，虽然这并不好。</font> </font></p>
<p><br />
<font color="#333333" size="2">----------------------------------------------------<br />
java的(PO,VO,TO,BO,DAO,POJO)解释<br />
<br />
PO(persistant object) 持久对象 <br />
在o/r映射的时候出现的概念，如果没有o/r映射，没有这个概念存在了。通常对应数据模型(数据库),本身还有部分业务逻辑的处理。可以看成是与数据库中的表相映射的java对象。最简单的PO就是对应数据库中某个表中的一条记录，多个记录可以用PO的集合。PO中应该不包含任何对数据库的操作。 </font></p>
<p><font color="#333333" size="2">VO(value object) 值对象 <br />
通常用于业务层之间的数据传递，和PO一样也是仅仅包含数据而已。但应是抽象出的业务对象,可以和表对应,也可以不,这根据业务的需要.个人觉得同DTO(数据传输对象),在web上传递。 </font></p>
<p><font color="#333333" size="2">TO(Transfer Object)，数据传输对象<br />
在应用程序不同tie(关系)之间传输的对象 </font></p>
<p><font color="#333333" size="2">BO(business object) 业务对象 <br />
从业务模型的角度看,见UML元件领域模型中的领域对象。封装业务逻辑的java对象,通过调用DAO方法,结合PO,VO进行业务操作。 </font></p>
<p><font color="#333333" size="2">POJO(plain ordinary java object) 简单无规则java对象<br />
纯的传统意义的java对象。就是说在一些Object/Relation Mapping工具中，能够做到维护数据库表记录的persisent object完全是一个符合Java Bean规范的纯Java对象，没有增加别的属性和方法。我的理解就是最基本的Java Bean，只有属性字段及setter和getter方法！。 </font></p>
<p><font color="#333333" size="2">DAO(data access object) 数据访问对象 <br />
是一个sun的一个标准j2ee设计模式，这个模式中有个接口就是DAO，它负持久层的操作。为业务层提供接口。此对象用于访问数据库。通常和PO结合使用，DAO中包含了各种数据库的操作方法。通过它的方法,结合PO对数据库进行相关的操作。夹在业务逻辑与数据库资源中间。配合VO, 提供数据库的CRUD操作... </font></p>
<p><font color="#333333" size="2">O/R Mapper 对象/关系 映射&nbsp;&nbsp; <br />
定义好所有的mapping之后，这个O/R Mapper可以帮我们做很多的工作。通过这些mappings,这个O/R Mapper可以生成所有的关于对象保存，删除，读取的SQL语句，我们不再需要写那么多行的DAL代码了。 </font></p>
<p><font color="#333333" size="2">实体Model(实体模式) <br />
DAL(数据访问层) <br />
IDAL(接口层) <br />
DALFactory(类工厂) <br />
BLL(业务逻辑层) <br />
BOF&nbsp;&nbsp;&nbsp;&nbsp; Business Object Framework&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 业务对象框架 <br />
SOA&nbsp;&nbsp;&nbsp;&nbsp; Service Orient Architecture&nbsp;&nbsp;&nbsp;&nbsp; 面向服务的设计 <br />
EMF&nbsp;&nbsp;&nbsp;&nbsp; Eclipse Model Framework&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Eclipse建模框架</font></p>
<p><font color="#333333" size="2">----------------------------------------<br />
</font></p>
<p><font color="#333300" size="2">PO：全称是<br />
persistant object持久对象<br />
最形象的理解就是一个PO就是数据库中的一条记录。<br />
好处是可以把一条记录作为一个对象处理，可以方便的转为其它对象。</font></p>
<p><font color="#333300" size="2">BO：全称是<br />
business object:业务对象<br />
主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。<br />
比如一个简历，有教育经历、工作经历、社会关系等等。<br />
我们可以把教育经历对应一个PO，工作经历对应一个PO，社会关系对应一个PO。<br />
建立一个对应简历的BO对象处理简历，每个BO包含这些PO。<br />
这样处理业务逻辑时，我们就可以针对BO去处理。</font></p>
<p><font color="#333300" size="2">VO ：<br />
value object值对象<br />
ViewObject表现层对象<br />
主要对应界面显示的数据对象。对于一个WEB页面，或者SWT、SWING的一个界面，用一个VO对象对应整个界面的值。</font></p>
<p><font color="#333300" size="2">DTO ：<br />
Data Transfer Object数据传输对象<br />
主要用于远程调用等需要大量传输对象的地方。<br />
比如我们一张表有100个字段，那么对应的PO就有100个属性。<br />
但是我们界面上只要显示10个字段，<br />
客户端用WEB service来获取数据，没有必要把整个PO对象传递到客户端，<br />
这时我们就可以用只有这10个属性的DTO来传递结果到客户端，这样也不会暴露服务端表结构.到达客户端以后，如果用这个对象来对应界面显示，那此时它的身份就转为VO</font></p>
<p><font color="#333300" size="2">POJO ：<br />
plain ordinary java object 简单java对象<br />
个人感觉POJO是最常见最多变的对象，是一个中间对象，也是我们最常打交道的对象。</font></p>
<p><font color="#333300" size="2">一个POJO持久化以后就是PO<br />
直接用它传递、传递过程中就是DTO<br />
直接用来对应表示层就是VO</font></p>
<p><font color="#333300" size="2">DAO：<br />
data access object数据访问对象<br />
这个大家最熟悉，和上面几个O区别最大，基本没有互相转化的可能性和必要.<br />
主要用来封装对数据库的访问。通过它可以把POJO持久化为PO，用PO组装出来VO、DTO</font></p>
<p><font color="#333333" size="2">-----------------------------------------------------------------</font></p>
<p><font color="#333333" size="2">PO:persistant object持久对象,可以看成是与数据库中的表相映射的java对象。最简单的PO就是对应数据库中某个表中的一条记录，多个记录可以用PO的集合。PO中应该不包含任何对数据库的操作.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
VO:value object值对象。通常用于业务层之间的数据传递，和PO一样也是仅仅包含数据而已。但应是抽象出的业务对象,可以和表对应,也可以不,这根据业务的需要.个人觉得同DTO(数据传输对象),在web上传递. </font></p>
<p><br />
<font color="#333333" size="2">DAO:data access object数据访问对象，此对象用于访问数据库。通常和PO结合使用，DAO中包含了各种数据库的操作方法。通过它的方法,结合PO对数据库进行相关的操作. </font></p>
<p><br />
<font color="#333333" size="2">BO:business object业务对象,封装业务逻辑的java对象,通过调用DAO方法,结合PO,VO进行业务操作; </font></p>
<p><br />
<font color="#333333" size="2">POJO:plain ordinary java object 简单无规则java对象,我个人觉得它和其他不是一个层面上的东西,VO和PO应该都属于它.</font></p>
<p><br />
<font color="#333333" size="2">---------------------------------------------<br />
<font color="#800000">VO：值对象、视图对象<br />
PO：持久对象<br />
QO：查询对象<br />
DAO：数据访问对象<br />
DTO：数据传输对象</font><br />
----------------------------------------<br />
struts 里的 ActionForm 就是个VO;<br />
hibernate里的 实体bean就是个PO,也叫POJO;<br />
hibernate里的Criteria 就相当于一个QO;<br />
在使用hibernate的时候我们会定义一些查询的方法,这些方法写在接口里,可以有不同的实现类.而这个接口就可以说是个DAO.<br />
个人认为QO和DTO差不多.<br />
----------------------------------------<br />
PO或叫BO，与数据库最接近的一层，是ORM中的O，基本上是数据库字段对应BO中的一个属性，为了同步与安全性考虑，最好只给DAO或者Service调用，而不要用packcode,backingBean,或者BO调。<br />
DAO，数据访问层，把VO，backingBean中的对象可以放入。。。。<br />
DTO，很少用，基本放入到DAO中，只是起到过渡的作用。<br />
QO，是把一些与持久性查询操作与语句放入。。<br />
VO，V层中用到的基本元素与方法等放其中。如果要其调用BO，则要做BO转换VO，VO转换BO操作。VO的好处是其页面的元素属性多于BO，可起到很好的作用。。。。<br />
-----------------------------------------<br />
楼上的不对吧，PO是持久化对象。BO＝business object—业务对象。<br />
PO可以严格对应数据库表，一张表对映一个PO。<br />
BO则是业务逻辑处理对象，我的理解是它装满了业务逻辑的处理，在业务逻辑复杂的应用中有用。<br />
VO：value object值对象、view object视图对象<br />
PO：持久对象<br />
QO：查询对象<br />
DAO：数据访问对象——同时还有DAO模式<br />
DTO：数据传输对象——同时还有DTO模式<br />
</font></p>
<img src ="http://www.blogjava.net/jkluooop/aggbug/267302.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jkluooop/" target="_blank">jkluooop</a> 2009-04-24 10:50 <a href="http://www.blogjava.net/jkluooop/archive/2009/04/24/267302.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>