dwr学习记录
一、认识DWR
dwr原理:在web.xml中配置dwr的servlet,这个servlet负责把前台的js代码封装成java去调用后台的java类方法,然后将返回结果(java类)再翻译成js返回,给我们的感觉就是在js中直接调用了java方法;
但实际上:代码的调用发生在服务器端,dwr在这个过程中负责了数据的传输和转换(dwr将java类动态的生成js)
dwr包含两部分:
- 一个运行在服务器端的 java servlet,它处理请求 和 返回响应给浏览器
- 一个运行在浏览器的 javascript,它发送请求 并且 动态的刷新页面
优点:配置相对简单,可以省略action层代码
缺点:暴露了后台java类方法
二、dwr官网示例
Java 从根本上讲是同步机制,然而 AJAX 却是异步的。所以你调用远程方法时,当数据已经从网络上返回的时候,你要提供有回调 (callback) 功能的 DWR。(通过回调函数来异步处理Java的函数调用过程)。
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包:
dwr.jar: [http://directwebremoting.org/dwr/downloads/index.html][http_directwebremoting.org_dwr_downloads_index.html]
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文件,添加
<!-- dwr配置 -->
<servlet>
<display-name>DWR Servlet</display-name>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<!-- 第一种方法:配置多个dwr.xml配置文件,之间用英文逗号隔开 -->
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/config/base/dwr.xml,/WEB-INF/config/bis/dwr.xml</param-value>
</init-param>
<!-- 允许调试,默认为false,调试地址:http://本机ip:8080/项目名/dwr/index.html -->
<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文件
第一个dwr配置文件 /WEB-INF/config/base/dwr.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
"http://getahead.org/dwr/dwr30.dtd ">
<dwr>
<allow>
<!-- 配置转换器, 指定返回给浏览器的实体类,也就是说指定了这个类类型后,可以返回这个类型给浏览器 -->
<convert converter="bean" match="com.chaol.vo.LsjmUser" />
<!-- spring管理的类配置,下面配置表示:将Spring管理的beanName为lsjmUserServiceImpl的类转换成lsUserSrc.js -->
<create creator="spring" javascript="lsUserSrc">
<param name="beanName" value="lsjmUserServiceImpl" />
</create>
</allow>
</dwr>
第二个dwr配置文件 /WEB-INF/config/bis/dwr.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
"http://getahead.org/dwr/dwr30.dtd ">
<!--
上面的dtd文件引入中, 版本需要跟你的导入项目的 dwr.jar文件对应
比如我项目中导入的时3.0版本的jar包, dtd文件也要引入3.0
如果是2.0版本的jar包:则需写:
DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
"http://getahead.org/dwr/dwr20.dtd"
-->
<dwr>
<allow>
<!-- 普通类中dwr配置 -->
<create creator="new" javascript="dwrDemo">
<param name="class" value="com.chaol.service.impl.DWRDemo"></param>
</create>
</allow>
</dwr>
3、 业务逻辑层(供dwr框架远程调用)
第一个service:
package com.chaol.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.chaol.mapper.LsjmUserMapper;
import com.chaol.service.LsjmUserService;
import com.chaol.vo.LsjmUser;
@Component(value="lsjmUserServiceImpl")
public class LsjmUserServiceImpl implements LsjmUserService {
@Autowired
private LsjmUserMapper lsjmUserMapper;
@Override
public LsjmUser getUser() {
return lsjmUserMapper.getUserByName();
}
public String test(){
return "success";
}
}
第二个service:
package com.chaol.service.impl;
public class DWRDemo {
public String dwrMethod(String result){
return result + ", success dwr !";
}
}
4、测试jsp页面(index.jsp,在项目根目录)
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>dwr demo index</title>
<!-- 引入dwr引擎js、工具js, 以及根据java类动态生成的js, 注意路径要写对 -->
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>
<script type="text/javascript" src="dwr/interface/lsUserSrc.js"></script>
<script type="text/javascript" src="dwr/interface/dwrDemo.js"></script>
</head>
<body>
<!-- 调用dwr -->
<a style="color:skyblue; cursor:pointer; " onclick="dwrFun()">dwr调用(spring)</a>
<br/>
<a style="color:skyblue; cursor:pointer;" onclick="dwrFun1()">dwr调用(普通类)</a>
</body>
<script>
function dwrFun(){
lsUserSrc.getUser(function(data){
console.log(data);
})
}
function dwrFun1(){
// 传入参数 ,data是服务端响应 返回给浏览器的数据
dwrDemo.dwrMethod("hello", function(data){
console.log(data);
})
}
</script>
</html>
5、测试结果截图:
Demo中分两个dwr.xml配置文件是想测试, 存在dwr.xml 文件时,该如何来配置,上面的代码中这样配置最后测试结果没有什么问题, 另外一种配置方式是分多个servlet分别加载:
<!-- 第一个dwr配置 -->
<servlet>
<display-name>DWR Servlet</display-name>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/config/base/dwr.xml</param-value>
</init-param>
<!-- 允许调试,默认为false,调试地址:http://本机ip:8080/项目名/dwr/index.html -->
<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的取值不能相同 -->
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<!-- 第一个dwr.xml配置 -->
<servlet>
<servlet-name>dwr-invoker1</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>config-admin</param-name>
<param-value>/WEB-INF/config/bis/dwr.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-invoker1</servlet-name>
<!-- 注意,这里多个url-pattern的取值不能相同 -->
<url-pattern>/dwr1/*</url-pattern>
</servlet-mapping>
此时,jsp中引入java类动态生成的js文件的路径也要跟着该变:
<!-- 引入dwr引擎js、工具js, 以及根据java类动态生成的js, 注意路径要写对 -->
<script type="text/javascript" src="dwr1/engine.js"></script>
<script type="text/javascript" src="dwr1/util.js"></script>
<!-- 这里是dwr1/.... ,要和web.xml中的配置对应起来 -->
<script type="text/javascript" src="dwr1/interface/dwrDemo.js"></script>
<!-- 引入dwr引擎js、工具js, 以及根据java类动态生成的js, 注意路径要写对 -->
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>
<!-- 这里是dwr1/.... ,要和web.xml中的配置对应起来 -->
<script type="text/javascript" src="dwr/interface/dwrDemo.js"></script>
如果用这个方法配置,此时有一个问题:
如果在一个jsp页面中,要引用多一个dwr,那必须按照上面的配置写,看上去每一个动态生成的js都有独立
的目录,比如dwr/.. 或者 dwr1/..., 但是实际上,后面的*/engine.js会覆盖前面的*/engine.js,
也就是按照上面的写法,其实起作用的dwr引擎js其实只有dwr/engine, 那么现在的问题是 如果用dwrDemo
的时候,它用的引擎不是dwr1/engine.js, 而是dwr/engine.js, 此时就会报错,在服务端是报
(Class not found),这个情况不知道有没有解决的方法,暂时没有找到
第一种配置方式不会存在这个问题, 因为它都是在dwr/engine.js下,
总结(dwr.xml中的配置):
2.0版本的dwr.jar,引入:
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
"http://getahead.org/dwr/dwr20.dtd ">
3.0版本的dwr.jar,引入:
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
"http://getahead.org/dwr/dwr30.dtd ">
// 1、一个简单的dwr配置
<dwr>
<allow>
<!-- 普通类中dwr配置 -->
<create creator="new" javascript="dwrDemo">
<param name="class" value="com.chaol.service.impl.DWRDemo"></param>
</create>
</allow>
</dwr>
//2、如果有自定义的返回类型,需要添加转换器; 处于安全考虑,dwr默认是不会转换这些类型的
<convert converter="bean" match="com.chaol.vo.LsjmUser" />
<convert converter="bean" match="com.chaol.vo.LsjmUser" >
<!-- 转换过程中,还可以指定只转换那些字段 -->
<param name="include" value="uname,pwd" />
</convert>
// 3、Spring管理的bean组件的dwr配置
<dwr>
<allow>
<!-- 配置转换器, 指定返回给浏览器的实体类,也就是说指定了这个类类型后,可以返回这个类型给浏览器 -->
<convert converter="bean" match="com.chaol.vo.LsjmUser" />
<!-- spring管理的类配置,下面配置表示:将Spring管理的beanName为lsjmUserServiceImpl的类转换成lsUserSrc.js -->
<create creator="spring" javascript="lsUserSrc">
<param name="beanName" value="lsjmUserServiceImpl" />
<!-- 指定只有getUser方法可用 -->
<include method="getUser" />
</create>
</allow>
</dwr>
// 4、前台页面引入dwr引擎js、工具js, 以及根据java类动态生成的js
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>
<script type="text/javascript" src="dwr/interface/lsUserSrc.js"></script>
//5、 多个dwr配置,参考上面的配置,这里不重复写
在web.xml中开启了dwr的debug后,可以在页面上调试方法,调试地址:http://本机ip:8080/项目名/dwr/index.html
比如我这个Demo中,在浏览器输入地址后,出现如下界面:
继续点击lsUserSrc, 这个就是dwr根据java类动态生成的javascript,
点击getUser()后面的 Execute 按钮, 会出现测试结果(如果逻辑、代码没问题的话):
过程中参考的两篇文章:
https://www.cnblogs.com/techlogy/p/5705758.html
https://blog.csdn.net/shb_derek1/article/details/24379221
还没有评论,来说两句吧...