DWR中文文档v0.9 09

xiaoxiao2021-03-01  19

第8章. DWR进阶8.1 DWR AnnotationsDWR标注是用来代替dwr.xml或者与其一同工作的。8.1.1 初始配置要使用DWR的标注,你需要在web.xml中配置不同的DWR控制器。

<servlet> <description>DWR controller servlet</description> <servlet-name>DWR controller servlet</servlet-name> <servlet-class> org.directwebremoting.servlet.DwrServlet </servlet-class> <init-param> <param-name>classes</param-name> <param-value> com.example.RemoteFunctions, com.example.RemoteBean </param-value> </init-param> </servlet>

 servlet参数classes定义的时可以标注的类的全名,这些名字用逗号分割。8.1.2 远程访问类要使一个简单的class可以成为远程访问类,你需要使用@Create和@RemoteMethod标注。

@Create public class RemoteFunctions { @RemoteMethod public int calculateFoo() { return 42; } }

 没有被@RemoteMethod标注的方法不能被远程访问。 要在Javascript使用不同于类型的名字,使用@Create标注的

name 属性。

@Create(name = "Functions") public class RemoteFunctions { }

 8.1.3 对象转换要使一个简单的bean类可以被远程访问, 使用@Convert和@RemoteProperty标注:

@Convert public class Foo { @RemoteProperty private int foo; public int getFoo() { return foo; } @RemoteProperty public int getBar() { return foo * 42; } }

 要使用复杂的转换器,使用@Convert标注的 converter 属性。

8.2 错误和异常处理

8.2.1 错误处理在1.0版中错误处理规则有些bug,1.1修复了这些错误。 DWR中有一些全局的处理器(一个错误相关的, 叫做

errorHandler, 另一个警告相关的, 叫做warningHandler)。DWR会默认指定一些全局处理器。你可以这样的改变

全局级别的处理器:

DWREngine.setErrorHandler(handler);

 你也可以指定单次调用和批量调用的错误和警告处理。例如,在调用元数据中:

Remote.method(params, { callback:function(data) { ... }, errorHandler:function(errorString, exception) { ... } });

 或者,在批量元数据中:

DWREngine.beginBatch(); Remote.method(params, function(data) { ... }); // 其他的远程调用 DWREngine.endBatch({ errorHandler:function(errorString, exception) { ... } });

 8.2.2 异常DWR可以转换异常,这样他们会变成Javascript中的错误(他们可以被抛出,因为这可能在异步调用中发生)。 例

如,如果我们远程调用下面的Java类:

public class Remote { public String getData() { throw new NullPointerException("message"); } }

 那么在Javascript中我们加入下面这些:

function eh(msg) { alert(msg); } { DWREngine.setErrorHandler(eh); Remote.getData(function(data) { alert(data); });

 结果会通过eh()错误处理器调用alert窗口的,显示消息 – 例如调用异常的getMessage()得到的消息。

8.2.3 找出更多的信息我们可以把整个异常传地到Javascript中。如果在dwr.xml中加入转换异常本身的能力:

<convert converter="bean" match="my.special.FunkyException"/>

 在这里例子中FunkyException被指定,因为它不仅仅包括一个消息,它还包括一些关于异常的额外数据。例如,

SQLException包含错误号,SAX异常包含错误的行和列等等。所以我们可以把上面的例如改为:

public class Remote { public String getData() { Date when = new Date(); throw new FunkyException("message", when); // FunkyException有一个getWhen()方法 } }

 然后在Javascript中是这样的:

function eh(msg, ex) { alert(msg + ", date=" + ex.when); } DWREngine.setErrorHandler(eh); Remote.getData(function(data) { alert(data); });

 结果会是一个eh()错误处理器调用的alert框,上面有这些信息:"message, date=Mon Jan 01 2008 10:00:00

GMT+0100" 被传递到错误处理器的ex对象会包含异常在服务端的所有属性,但是异常栈信息没有。

8.3 传递额外的数据到callback函数通常我们需要传递额外的数据到callback函数,但是因为所有的回调函数都只有一个参数(远程方法的返回结果)

,这就需要一些小技巧了。 解决方案就是使用Javascript的闭包特性。 例如,你的回调函数原本需要像这个样

子:

function callbackFunc(dataFromServer, dataFromBrowser) { // 用dataFromServer和dataFromBrowser做些事情...... }

 那么你可以像这个组织你的函数:

var dataFromBrowser = ...; // 定义一个闭包函数来存储dataFromBrowser的引用,并调用dataFromServer var callbackProxy = function(dataFromServer) { callbackFunc(dataFromServer, dataFromBrowser); }; var callMetaData = { callback:callbackProxy }; Remote.method(params, callMetaData);

 换句话说,现在你作为callback函数传递过来的不是一个真正的callback,他只是一个做为代理的闭包,用来传

递客户端的数据。 你可以用更简介的形式:

var dataFromBrowser = ...; Remote.method(params, { callback:function(dataFromServer) { callbackFunc(dataFromServer, dataFromBrowser); } });

 8.4 从其他的URL读取数据如果你需要读取其他web应用程序生成的页面,并返回到Javascript中。非常简单。只要在你的Java类里面包括下

面这写代码:

public String getInclude() throws ServletException, IOException{ return WebContextFactory.get().forwardToString("/forward.jsp"); }

 很明显你应该把"/forward.jsp"替换成你要forward到的页面的URL。这个URL必须以一个斜杠开始,因为它只是调

用 HttpRequest.forward() 。 你可以用这个方法在传递之前任何定制你的页面。 8.5 安全我们很谨慎的对待DWR的安全问题,并且认为有必要解释一下避免错误要做的事情。 首先DWR让你明确哪些是被远

程调用的,是如何被远程调用。原则就是DWR必须调用那些你明确允许的代码。 dwr.xml要求你为每一个远程类定

义一个'create'项。你还可以通过指定include和exclude元素来更精确的控制远程调用Bean中可以被调用的方法

。 除此之外如果你希望允许DWR在转换你的JavaBean到Javascript或者从Javascript转换到JavaBean时有一定的

许可限制,同样可以精确控制哪些Bean的属性可以被转换。 一个很明显但又必须指出的 – 不要在生产环境中打

开test/debug模式控制台。如何打开或关闭debug控制台在配置web.xml部分可以找到详细描述。 审查 - DWR带来的最大好处很值得对比一下DWR和Servlet、JSP或周围的其他web框架。 如果你要审查基于DWR的功能,那是非常简单的。看

看dwr.xml你就能得到一个哪些方法被暴露到外面的描述了。你也可以俯视全局用DWR可以访问哪些资源。 但是要

在其他系统里做这件事可不是这么容易。如果是Servlet你需要检查WEB-INF/web.xml文件,然后检查写在Servlet

中的request.getParameter(...)。如果是Struts和其他Framework你需要检查配置文件,然后顺着流程检查代码

,看请求信息出了什么问题。 访问控制DWR允许你通过两种基于J2EE的机制来进行访问控制。首先你可以基于J2EE角色定义DWR的访问。其次你可以在DWR

里面定义访问方法的角色。 其他方面DWR不允许你定义任何内部类的create和convert。这样设计是为了不出现意外的攻击来操作DWR的核心文件以提升

访问权限。 风险有什么机会可以让攻击者窥视你的系统呢?使用DWR你攻击者可以使服务器创建任何你在dwr.xml中指定的Java对

象的实例。并且(如果你用BeanConverter)Java类的任何方法、以及方法任何参数都是可见的。这些类的任何一个

属性都有可能是攻击者需要的。 如果你知道DWR是怎么工作的,这些都是很显而易见的结论,但是往往粗心会造

成问题。如果你创建了一个有appendStringToFile()方法的FileBean的类,而且用DWR把它暴露出去,那么你就给

了攻击者一个机会来填满你的文件系统。 你必须时刻注意用了DWR以后,有没有给攻击者什么机会。 一般来说这样的情景让人感觉使用DWR是有风险的,但

是这样的问题在所有的传统web架构中都存在,只是在那些架构中这些不明显,所以就很难被修复。 保证更加安全这已经很安全了,那么你还能做什么来保证更加安全了?首先记住上面这些关于审查的内容,当web应用的其他地

方不安全时,即使它看上去很安全,过多的关注DWR是很愚蠢的。如果DWR让人感觉恐惧,那是因为它的问题都在

明处。所以第一步是多检查几遍传统架构的问题。 你可以通过把可远程访问的类放到不同的包里,并且使用代理

来防止DWR访问机制出问题。如果你愿意还可以再次检查基于角色的安全控制。这些内容只是在检查DWR已经为你

做的事情。 比多检查几次更好的方法是检查DWR的源码,保证它是在正确的工作。这些代码已经被很多人检查过

了,但多双眼睛总是有好处的。 整合AcegiDWR可以整合Acegi security framework。更多的信息见整合DWR和Acegi. 

相关资源:微信小程序源码-合集1.rar
转载请注明原文地址: https://www.6miu.com/read-3199987.html

最新回复(0)