dwr学习记录

一、认识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官网示例 

    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

    commons-logging.jar :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

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值