dwr学习记录

谁践踏了优雅 2022-05-11 07:08 318阅读 0赞

一、认识DWR

dwr原理:在web.xml中配置dwr的servlet,这个servlet负责把前台的js代码封装成java去调用后台的java类方法,然后将返回结果(java类)再翻译成js返回,给我们的感觉就是在js中直接调用了java方法;

但实际上:代码的调用发生在服务器端,dwr在这个过程中负责了数据的传输和转换(dwr将java类动态的生成js)

dwr包含两部分:

  1. 一个运行在服务器端的 java servlet,它处理请求 和 返回响应给浏览器
  2. 一个运行在浏览器的 javascript,它发送请求 并且 动态的刷新页面

优点:配置相对简单,可以省略action层代码

缺点:暴露了后台java类方法

二、dwr官网示例 

  1. Java 从根本上讲是同步机制,然而 AJAX 却是异步的。所以你调用远程方法时,当数据已经从网络上返回的时候,你要提供有回调 callback 功能的 DWR。(通过回调函数来异步处理Java的函数调用过程)。

70

  1. DWR 动态在 JavaScript 里生成一个 AjaxService 类,去匹配服务器端的代码。eventHandler 方法去调用服务器端代码,然后 DWR 处理所有的远程细节,包括**转换(converting 所有的参数**以及**返回 Javascript Java 之的值**。在示例中,先在 eventHandler 方法里调用 AjaxService getOptions() 方法,然后通过**回调方法 populateList(data) 得到返回的数据**,其中 data 就是 String\[\]\{"1", "2", "3"\},最后再使用 DWR utility data 加入到下拉列表。

#

三、Demo(普通web项目,非maven工程,spring+mybatis+dwr)

准备工作:下载jar包:

  1. dwr.jar [http://directwebremoting.org/dwr/downloads/index.html][http_directwebremoting.org_dwr_downloads_index.html]
  2. commons-logging.jar :[http://commons.apache.org/proper/commons-logging/download\_logging.cgi][http_commons.apache.org_proper_commons-logging_download_logging.cgi] dwr.jar依赖这个jar

Demo核心部分详细配置展示:

1、配置web.xml文件,添加

  1. <!-- dwr配置 -->
  2. <servlet>
  3. <display-name>DWR Servlet</display-name>
  4. <servlet-name>dwr-invoker</servlet-name>
  5. <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  6. <!-- 第一种方法:配置多个dwr.xml配置文件,之间用英文逗号隔开 -->
  7. <init-param>
  8. <param-name>config</param-name>
  9. <param-value>/WEB-INF/config/base/dwr.xml,/WEB-INF/config/bis/dwr.xml</param-value>
  10. </init-param>
  11. <!-- 允许调试,默认为false,调试地址:http://本机ip:8080/项目名/dwr/index.html -->
  12. <init-param>
  13. <param-name>debug</param-name>
  14. <param-value>true</param-value>
  15. </init-param>
  16. </servlet>
  17. <servlet-mapping>
  18. <servlet-name>dwr-invoker</servlet-name>
  19. <url-pattern>/dwr/*</url-pattern>
  20. </servlet-mapping>

2、配置dwr.xml文件

第一个dwr配置文件 /WEB-INF/config/base/dwr.xml :

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE dwr PUBLIC
  3. "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
  4. "http://getahead.org/dwr/dwr30.dtd ">
  5. <dwr>
  6. <allow>
  7. <!-- 配置转换器, 指定返回给浏览器的实体类,也就是说指定了这个类类型后,可以返回这个类型给浏览器 -->
  8. <convert converter="bean" match="com.chaol.vo.LsjmUser" />
  9. <!-- spring管理的类配置,下面配置表示:将Spring管理的beanName为lsjmUserServiceImpl的类转换成lsUserSrc.js -->
  10. <create creator="spring" javascript="lsUserSrc">
  11. <param name="beanName" value="lsjmUserServiceImpl" />
  12. </create>
  13. </allow>
  14. </dwr>

第二个dwr配置文件 /WEB-INF/config/bis/dwr.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE dwr PUBLIC
  3. "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
  4. "http://getahead.org/dwr/dwr30.dtd ">
  5. <!--
  6. 上面的dtd文件引入中, 版本需要跟你的导入项目的 dwr.jar文件对应
  7. 比如我项目中导入的时3.0版本的jar包, dtd文件也要引入3.0
  8. 如果是2.0版本的jar包:则需写:
  9. DOCTYPE dwr PUBLIC
  10. "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
  11. "http://getahead.org/dwr/dwr20.dtd"
  12. -->
  13. <dwr>
  14. <allow>
  15. <!-- 普通类中dwr配置 -->
  16. <create creator="new" javascript="dwrDemo">
  17. <param name="class" value="com.chaol.service.impl.DWRDemo"></param>
  18. </create>
  19. </allow>
  20. </dwr>

3、 业务逻辑层(供dwr框架远程调用)

第一个service:

  1. package com.chaol.service.impl;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.stereotype.Component;
  4. import com.chaol.mapper.LsjmUserMapper;
  5. import com.chaol.service.LsjmUserService;
  6. import com.chaol.vo.LsjmUser;
  7. @Component(value="lsjmUserServiceImpl")
  8. public class LsjmUserServiceImpl implements LsjmUserService {
  9. @Autowired
  10. private LsjmUserMapper lsjmUserMapper;
  11. @Override
  12. public LsjmUser getUser() {
  13. return lsjmUserMapper.getUserByName();
  14. }
  15. public String test(){
  16. return "success";
  17. }
  18. }

第二个service:

  1. package com.chaol.service.impl;
  2. public class DWRDemo {
  3. public String dwrMethod(String result){
  4. return result + ", success dwr !";
  5. }
  6. }

4、测试jsp页面(index.jsp,在项目根目录)

  1. <%@ page language="java" contentType="text/html; charset=utf-8"
  2. pageEncoding="utf-8"%>
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  7. <title>dwr demo index</title>
  8. <!-- 引入dwr引擎js、工具js, 以及根据java类动态生成的js, 注意路径要写对 -->
  9. <script type="text/javascript" src="dwr/engine.js"></script>
  10. <script type="text/javascript" src="dwr/util.js"></script>
  11. <script type="text/javascript" src="dwr/interface/lsUserSrc.js"></script>
  12. <script type="text/javascript" src="dwr/interface/dwrDemo.js"></script>
  13. </head>
  14. <body>
  15. <!-- 调用dwr -->
  16. <a style="color:skyblue; cursor:pointer; " onclick="dwrFun()">dwr调用(spring)</a>
  17. <br/>
  18. <a style="color:skyblue; cursor:pointer;" onclick="dwrFun1()">dwr调用(普通类)</a>
  19. </body>
  20. <script>
  21. function dwrFun(){
  22. lsUserSrc.getUser(function(data){
  23. console.log(data);
  24. })
  25. }
  26. function dwrFun1(){
  27. // 传入参数 ,data是服务端响应 返回给浏览器的数据
  28. dwrDemo.dwrMethod("hello", function(data){
  29. console.log(data);
  30. })
  31. }
  32. </script>
  33. </html>

5、测试结果截图:

70 1

Demo中分两个dwr.xml配置文件是想测试, 存在dwr.xml 文件时,该如何来配置,上面的代码中这样配置最后测试结果没有什么问题, 另外一种配置方式是分多个servlet分别加载:

  1. <!-- 第一个dwr配置 -->
  2. <servlet>
  3. <display-name>DWR Servlet</display-name>
  4. <servlet-name>dwr-invoker</servlet-name>
  5. <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  6. <init-param>
  7. <param-name>config</param-name>
  8. <param-value>/WEB-INF/config/base/dwr.xml</param-value>
  9. </init-param>
  10. <!-- 允许调试,默认为false,调试地址:http://本机ip:8080/项目名/dwr/index.html -->
  11. <init-param>
  12. <param-name>debug</param-name>
  13. <param-value>true</param-value>
  14. </init-param>
  15. </servlet>
  16. <servlet-mapping>
  17. <servlet-name>dwr-invoker</servlet-name>
  18. <!-- 注意,这里多个url-pattern的取值不能相同 -->
  19. <url-pattern>/dwr/*</url-pattern>
  20. </servlet-mapping>
  21. <!-- 第一个dwr.xml配置 -->
  22. <servlet>
  23. <servlet-name>dwr-invoker1</servlet-name>
  24. <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  25. <init-param>
  26. <param-name>config-admin</param-name>
  27. <param-value>/WEB-INF/config/bis/dwr.xml</param-value>
  28. </init-param>
  29. <init-param>
  30. <param-name>debug</param-name>
  31. <param-value>true</param-value>
  32. </init-param>
  33. </servlet>
  34. <servlet-mapping>
  35. <servlet-name>dwr-invoker1</servlet-name>
  36. <!-- 注意,这里多个url-pattern的取值不能相同 -->
  37. <url-pattern>/dwr1/*</url-pattern>
  38. </servlet-mapping>

此时,jsp中引入java类动态生成的js文件的路径也要跟着该变:

  1. <!-- 引入dwr引擎js、工具js, 以及根据java类动态生成的js, 注意路径要写对 -->
  2. <script type="text/javascript" src="dwr1/engine.js"></script>
  3. <script type="text/javascript" src="dwr1/util.js"></script>
  4. <!-- 这里是dwr1/.... ,要和web.xml中的配置对应起来 -->
  5. <script type="text/javascript" src="dwr1/interface/dwrDemo.js"></script>
  6. <!-- 引入dwr引擎js、工具js, 以及根据java类动态生成的js, 注意路径要写对 -->
  7. <script type="text/javascript" src="dwr/engine.js"></script>
  8. <script type="text/javascript" src="dwr/util.js"></script>
  9. <!-- 这里是dwr1/.... ,要和web.xml中的配置对应起来 -->
  10. <script type="text/javascript" src="dwr/interface/dwrDemo.js"></script>
  11. 如果用这个方法配置,此时有一个问题:
  12. 如果在一个jsp页面中,要引用多一个dwr,那必须按照上面的配置写,看上去每一个动态生成的js都有独立
  13. 的目录,比如dwr/.. 或者 dwr1/..., 但是实际上,后面的*/engine.js会覆盖前面的*/engine.js,
  14. 也就是按照上面的写法,其实起作用的dwr引擎js其实只有dwr/engine, 那么现在的问题是 如果用dwrDemo
  15. 的时候,它用的引擎不是dwr1/engine.js, 而是dwr/engine.js, 此时就会报错,在服务端是报
  16. (Class not found),这个情况不知道有没有解决的方法,暂时没有找到
  17. 第一种配置方式不会存在这个问题, 因为它都是在dwr/engine.js下,

总结(dwr.xml中的配置):

  1. 2.0版本的dwr.jar,引入:
  2. <!DOCTYPE dwr PUBLIC
  3. "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
  4. "http://getahead.org/dwr/dwr20.dtd ">
  5. 3.0版本的dwr.jar,引入:
  6. <!DOCTYPE dwr PUBLIC
  7. "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
  8. "http://getahead.org/dwr/dwr30.dtd ">
  9. // 1、一个简单的dwr配置
  10. <dwr>
  11. <allow>
  12. <!-- 普通类中dwr配置 -->
  13. <create creator="new" javascript="dwrDemo">
  14. <param name="class" value="com.chaol.service.impl.DWRDemo"></param>
  15. </create>
  16. </allow>
  17. </dwr>
  18. //2、如果有自定义的返回类型,需要添加转换器; 处于安全考虑,dwr默认是不会转换这些类型的
  19. <convert converter="bean" match="com.chaol.vo.LsjmUser" />
  20. <convert converter="bean" match="com.chaol.vo.LsjmUser" >
  21. <!-- 转换过程中,还可以指定只转换那些字段 -->
  22. <param name="include" value="uname,pwd" />
  23. </convert>
  24. // 3、Spring管理的bean组件的dwr配置
  25. <dwr>
  26. <allow>
  27. <!-- 配置转换器, 指定返回给浏览器的实体类,也就是说指定了这个类类型后,可以返回这个类型给浏览器 -->
  28. <convert converter="bean" match="com.chaol.vo.LsjmUser" />
  29. <!-- spring管理的类配置,下面配置表示:将Spring管理的beanNamelsjmUserServiceImpl的类转换成lsUserSrc.js -->
  30. <create creator="spring" javascript="lsUserSrc">
  31. <param name="beanName" value="lsjmUserServiceImpl" />
  32. <!-- 指定只有getUser方法可用 -->
  33. <include method="getUser" />
  34. </create>
  35. </allow>
  36. </dwr>
  37. // 4、前台页面引入dwr引擎js、工具js, 以及根据java类动态生成的js
  38. <script type="text/javascript" src="dwr/engine.js"></script>
  39. <script type="text/javascript" src="dwr/util.js"></script>
  40. <script type="text/javascript" src="dwr/interface/lsUserSrc.js"></script>
  41. //5、 多个dwr配置,参考上面的配置,这里不重复写

在web.xml中开启了dwr的debug后,可以在页面上调试方法,调试地址:http://本机ip:8080/项目名/dwr/index.html

比如我这个Demo中,在浏览器输入地址后,出现如下界面:

70 2

继续点击lsUserSrc, 这个就是dwr根据java类动态生成的javascript,

70 3

点击getUser()后面的 Execute 按钮, 会出现测试结果(如果逻辑、代码没问题的话):

70 4

过程中参考的两篇文章:

https://www.cnblogs.com/techlogy/p/5705758.html

https://blog.csdn.net/shb_derek1/article/details/24379221

发表评论

表情:
评论列表 (有 0 条评论,318人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SSH2+dwr

    很早之前就想写博客,可是一直没动手。这两天闲的无聊又玩起了搭框架的“游戏”,搭完才发现真的是“好记性不如烂笔头”,很多东西都忘了,遂下定决心开始写博客。 在讲SSH2和dwr

    相关 DWR

    DWR(Direct Web Remoting)是Java和JavaScript相结合的开源库,通过它可以简单、容易地构建Ajax程序,开发者无需了解 XMLHttpReque

    相关 dwr学习

    dwr学习 DWR是一个远程调用库,用于js调用java函数或者java调用js函数。 DWR主要由下面两部分组成: 运行一个Java Servlet服务器,接

    相关 dwr学习记录

    一、认识DWR dwr原理:在web.xml中配置dwr的servlet,这个servlet负责把前台的js代码封装成java去调用后台的java类方法,然后将返回结果(