`
talentkep
  • 浏览: 97921 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

DWR work

    博客分类:
阅读更多

这段时间较闲,研究了一番dwr.发现dwr实现的AJAX有些地方确实很是先进.比如动态生成javascript代码;隐藏的http协议;javascript于java代码交互的是javascript对象(或字符串)等.
以下是我临时译的一些东西.本来想全译,发现dwr实在是简单,就随便写了.英文居差,现一把.

1、DWR: Easy AJAX for JAVA

作为一个java open source library,DWR可以帮助开发人员完成应用AJAX技术的web程序。它可以让浏览器上的javascript方法调用运行在web服务器上java方法。

DWR主要由两部门组成。javascript与web服务器通信并更新web页;运行在web服务器的Servlet处理请求并把响应发回浏览器。

DWR采用新颖的方法实现了AJAX(本来也没有确切的定义),在java代码基础上动态的生成javascript代码。web开发者可以直接调用这些javascript代码,然而真正的代码是运行在web服务器上的java code。出与安全考虑,开发者必须配置哪些java class暴露给DWR.(dwr.xml)

这种从(java到javascript)调用机制给用户一种感觉,好象常规的RPC机制,或RMI or SOAP.但是它运行在web上,不需要任何浏览器插件。

DWR不认为浏览器和web服务器之间协议重要,把系统界面放在首位。最大挑战是java method call的同步特征与ajax异步特性之间的矛盾。在异步模型里,结果只有在方法结束后才有效。DWR解决了这个问题,把回调函数当成参数传给方法,处理完成后,自动调用回调方法。

这个图表显示了,通过javascript事件,DWR能改变select的内容,当然这些内容由java代码返回。 javascript函数Data.getOptions(populateList)由DWR动态生成,这个函数会调用java class Data类的方法。DWR处理如何远程调用,包括转换所有的参数和返回的结果(javascript\java)。java方法执行完后,执行回调方法populateList。在整个过程中我们就想在用本地的方法一样。

2、Getting Started

废话少说,试试就ok了。
web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app id="dwr">
  <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>
</web-app>

dwr.xml  与web.xml同目录
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
  <allow>
    <create creator="new" javascript="JDate">
      <param name="class" value="java.util.Date"/>
    </create>
  </allow>
</dwr>

index.html
<html>
<head>
  <title>DWR - Test Home</title>
  <script type='text/javascript' src='dwr/interface/JDate.js'></script>
  <script type='text/javascript' src='dwr/engine.js'></script>
  <script>
    function init(){
        JDate.getYear(load);
    }
    function load(data){
      alert(data+1900+'年')
    }
  </script>
</head>
<body onload="init()">
</body>
</html>

dwr.jar  下载放lib下

完了,什么,够了,就这些。访问ok!
3、Examples
http://www.aboutmyhealth.org/  这不是Google Suggest吗!ok.
4、源码浅析
dwr的设计很象webwork2的设计,隐藏http协议,扩展性,兼容性及强。

通过研究uk.ltd.getahead.dwr.DWRServlet这个servlet来研究下dwr到底是如何工作滴。

Java代码 复制代码
  1. web.xml配置   
  2. <servlet>   
  3.     <servlet-name>dwr-invoker</servlet-name>   
  4.     <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>   
  5.   </servlet>   
  6.   <servlet-mapping>   
  7.     <servlet-name>dwr-invoker</servlet-name>   
  8.     <url-pattern>/dwr/*</url-pattern>   
  9. </servlet-mapping>   
  10. 这样所有的/dwr/*所有请求都由这个servlet来处理,它到底处理了些什么能。我们还以上面最简单的例子来看。   
  11. 1、  web服务器启动,DWRServlet init()方法调用,init主要做了以下工作。   
  12. 设置日志级别、实例化DWR用到的单例类(这些类在jvm中只有一个实例对象)、读去配置文件(包括dwr.jar包中的dwr.xml,WEB-INF/dwr.xml. config*.xml)。   
  13. 2、请求处理   
  14. DWRServlet.doGet, doPost方法都调用processor.handle(req, resp)方法处理。Processor对象在init()方法中已经初始化了。   
  15. <PRE class=java name="code">public void handle(HttpServletRequest req, HttpServletResponse resp);   
  16.         throws IOException   
  17.     {   
  18.         String pathinfo = req.getPathInfo();;   
  19.         if(pathinfo == null || pathinfo.length(); == 0 || pathinfo.equals("/"););   
  20.         {   
  21.             resp.sendRedirect(req.getContextPath(); + req.getServletPath(); + '/' + "index.html");;   
  22.         } else  
  23.         if(pathinfo != null && pathinfo.equalsIgnoreCase("/index.html"););   
  24.         {   
  25.             doIndex(req, resp);;   
  26.         } else  
  27.         if(pathinfo != null && pathinfo.startsWith("/test/"););   
  28.         {   
  29.             doTest(req, resp);;   
  30.         } else  
  31.         if(pathinfo != null && pathinfo.equalsIgnoreCase("/engine.js"););   
  32.         {   
  33.             doFile(resp, "engine.js""text/javascript");;   
  34.         } else  
  35.         if(pathinfo != null && pathinfo.equalsIgnoreCase("/util.js"););   
  36.         {   
  37.             doFile(resp, "util.js""text/javascript");;   
  38.         } else  
  39.         if(pathinfo != null && pathinfo.equalsIgnoreCase("/deprecated.js"););   
  40.         {   
  41.             doFile(resp, "deprecated.js""text/javascript");;   
  42.         } else  
  43.         if(pathinfo != null && pathinfo.startsWith("/interface/"););   
  44.         {   
  45.             doInterface(req, resp);;   
  46.         } else  
  47.         if(pathinfo != null && pathinfo.startsWith("/exec"););   
  48.         {   
  49.             doExec(req, resp);;   
  50.         } else  
  51.         {   
  52.             log.warn("Page not found. In debug/test mode try viewing /[WEB-APP]/dwr/");;   
  53.             resp.sendError(404);;   
  54.         }   
  55.     }</PRE>   
  56. <BR>哦。这些恍然大悟。dwr/*处理的请求也就这几种。   
  57. <BR>(1)dwr/index.html,dwr/test/这种只能在debug模式下使用,调试用。   
  58. <BR>dwr/engine.js,dwr/util.js,dwr/deprecated.js当这个请求到达,从dwr.jar包中读取文件流,响应回去。(重复请求有缓存)   
  59. <BR>(2)当dwr/interface/这种请求到来,(例如我们在index.html中的 <script type='text/javascript' src='dwr/interface/JDate.js'></script>)DWR做一件伟大的事。把我们在WEB-INF/dwr.xml中的   
  60. <BR><create creator="new" javascript="JDate">   
  61. <BR>      <param name="class" value="java.util.Date"/>   
  62. <BR></create>   
  63. <BR>java.util.Date转化为javascript函数。   
  64. <BR>http://localhost:port/simpledwr/dwr/interface/JDate.js看看吧。   
  65. <BR>细节也比较简单,通过java反射,把方法都写成javascript特定的方法。(我觉得这些转换可以放到缓存里,下次调用没必要再生成一遍,不知道作者为什么没这样做)。   
  66. <BR>(3)dwr/exec   
  67. <BR>    javascript调用方法时发送这种请求,可能是XMLHttpRequest或IFrame发送。   
  68. <BR>当然,javascript调用的方法签名与java代码一致,包括参数,还有javascript的回调方法也传到了服务器端,在服务器端很容易实现。回调方法的java的执行结果 返回类似 <script>callMethod(结果)<script>的javascript字符串,在浏览器执行。哈,一切就这么简单,巧妙。   
  69. <BR>   
  70. <BR>dwr的设计构思很是巧妙。   
  71. <BR>第一、把java类转化为javascript类由dwr自动完成,只需简单的配置。   
  72. <BR>第二、应用起来极其简单。开发者不要该服务器代码就可以集成。   
  73. <BR>第三、容易测试。和webwork一样,隐藏的http协议。   
  74. <BR>第四、及强扩展性。例如与spring集成,只需修改一点代码。   
  75. <BR>第五、性能。就我与jason,等简单比较,dwr性能可能是最好的。   
  76. <BR>第六、自动把java对象转化为javascript对象,并且及易扩展。

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////// 灰常华丽的分割线                                                         //////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

1、最小配置

 

Java代码 复制代码
  1. <servlet>   
  2.   <servlet-name>dwr-invoker</servlet-name>   
  3.   <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>   
  4. </servlet>   
  5. <servlet-mapping>   
  6.   <servlet-name>dwr-invoker</servlet-name>   
  7.   <url-pattern>/dwr/*</url-pattern>   
  8. </servlet-mapping>  
<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>


2、当我们想看DWR自动生成的测试页(Using debug/test mode)时,可在

Java代码 复制代码
  1. servlet中加   
  2. <init-param>   
  3.   <param-name>debug</param-name>   
  4.   <param-value>true</param-value>   
  5. </init-param>  
servlet中加
<init-param>
  <param-name>debug</param-name>
  <param-value>true</param-value>
</init-param>

这个参数DWR默认是false.如果选择true.我们可以通过url http://localhost:port/app/dwr  ,你就可以看到你部署的每个DWR class。并且可以测试java代码的每个方法是否运行正常。为了安全考虑,在正式环境下你一定把这个参数设为false.
3、logging信息配置。
在无java.util.logging的jdk1.3下运行DWR,我们不希望强制用户加一个logging包,而是用HttpServlet.log()方法来输出日志。如果classpath中包括logging jar包,DWR自动切换用logging输出日志。
如果用HttpServlet.log()方法,以下配置是有效的。

Java代码 复制代码
  1. <init-param>   
  2.  <param-name>logLevel</param-name>   
  3.  <param-value>DEBUG</param-value>   
  4. </init-param>  
<init-param>
 <param-name>logLevel</param-name>
 <param-value>DEBUG</param-value>
</init-param>

有效的值是  FATAL, ERROR, WARN (the default), INFO and DEBUG

我是喜欢用log4j输出日志,那么在log4j.properties下加,log4j.logger.uk.ltd.getahead.dwr = debug。这样可以看DWR的调试日志。
4、多dwr.xml文件的配置
可能有几种情况,我们一一列举。 一个servlet,多个dwr.xml配置文件;多个servlet,每个servlet对应一个或多个dwr.xml.
一个servlet,多个dwr.xml配置文件;

Java代码 复制代码
  1. <servlet>   
  2.     <servlet-name>dwr-invoker</servlet-name>   
  3.     <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>    
  4.     <init-param>   
  5.       <param-name>config-1</param-name>   
  6.       <param-value>WEB-INF/dwr1.xml</param-value>   
  7.     </init-param>   
  8.     <init-param>   
  9.       <param-name>config-2</param-name>   
  10.       <param-value>WEB-INF/dwr2.xml</param-value>   
  11.     </init-param>   
  12. </servlet>  
<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>

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

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

Java代码 复制代码
  1. <servlet>   
  2.    <servlet-name>dwr-invoker</servlet-name>   
  3.     <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>    
  4. <!--用classes/dwr.xml-->   
  5. </servlet>   
  6. <servlet>   
  7.    <servlet-name>dwr-invoker1</servlet-name>   
  8.    <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>    
  9.    <init-param>   
  10.      <param-name>config-admin</param-name>   
  11.      <param-value>WEB-INF/dwr1.xml</param-value>   
  12.    </init-param>   
  13.    <init-param>   
  14.      <param-name>debug</param-name>   
  15.      <param-value>true</param-value>   
  16.    </init-param>   
  17. </servlet>   
  18. <servlet-mapping>   
  19.    <servlet-name>dwr-invoker</servlet-name>   
  20.    <url-pattern>/dwr/*</url-pattern>   
  21. </servlet-mapping>   
  22. <servlet-mapping>   
  23.    <servlet-name>dwr-invoker1</servlet-name>   
  24.    <url-pattern>/dwr1/*</url-pattern>   
  25. </servlet-mapping>  
<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>

在这种情况下,我们可以根据J2EE security来控制权限,针对不同url,加不同的角色。
5、dwr的几个扩展点(Plug-ins)
DWR对以下接口提供的默认的实现,用户可以继承DWR的默认实现类来达到我们想要的效果。但这至少需要我们读了DWR源码才能做这些工作(dwr源码很是清晰,有兴趣可以学习一下),以后可能补存这部分。

Java代码 复制代码
  1. uk.ltd.getahead.dwr.AccessControl       
  2. uk.ltd.getahead.dwr.Configuration    
  3. uk.ltd.getahead.dwr.ConverterManager    
  4. uk.ltd.getahead.dwr.CreatorManager    
  5. uk.ltd.getahead.dwr.Processor    
  6. uk.ltd.getahead.dwr.ExecutionContext   
分享到:
评论

相关推荐

    DWR2项目实践 用例源代码(2)

    away without any further work on your part. You will also find a directory that matches the name of the webapp. This is the webapp in exploded format with all the source code. If you wish to ...

    DWR2项目实践 用例源代码(3)

    away without any further work on your part. You will also find a directory that matches the name of the webapp. This is the webapp in exploded format with all the source code. If you wish to ...

    DWR2项目实践 用例源代码(4)

    away without any further work on your part. You will also find a directory that matches the name of the webapp. This is the webapp in exploded format with all the source code. If you wish to ...

    DWR2项目实践 用例源代码(5)

    away without any further work on your part. You will also find a directory that matches the name of the webapp. This is the webapp in exploded format with all the source code. If you wish to ...

    DWR2项目实践 用例源代码(1)

    away without any further work on your part. You will also find a directory that matches the name of the webapp. This is the webapp in exploded format with all the source code. If you wish to ...

    Pro Ajax and Java Frameworks

    They also explain Log4js (and other tools) for JavaScript logging, JsUnit (and others) for testing, and various libraries like AjaxTags, DWR, and Script.aculo.us for rapid code development. ...

    Portlets in action

    Along the way, you’ll learn how to work with key web frameworks like Spring 3.0 Portlet MVC and DWR. Written for Java developers. No prior experience with portlets required What’s Inside ...

    Velocity Suite 1.2.3

    I have created a .dwr search query that will find velocity code that does not meet this standard and replace it with the correct spacing. see http://velocity.gilluminate.com to obtain it.] [Version ...

    Spring Recipes: A Problem-Solution Approach, Second Edition

    * Delivering web applications with Spring Web Flow, Spring MVC, Spring Portals, Struts, JSF, DWR, the Grails framework, and more. * Developing web services using Spring WS and REST; contract-last ...

    Professional Ajax

    Examples of how to call web services from the client are explained, as well as how to create server-side proxies to work around browser security restrictions. Chapter 7: "JSON." This ...

    jquery插件使用方法大全

    // perform other work here ... // Set another completion function for the request above jxhr.complete(function(){ alert&#40;"second complete"&#41;; }); 此外,使用jQuery.Deferred还可以开发自己的延迟...

Global site tag (gtag.js) - Google Analytics