加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

DWR学习笔记

发布时间:2020-12-15 21:58:49 所属栏目:百科 来源:网络整理
导读:1. 简介 DWR(Direct Web Remoting) 是一个 Java 开源框架,一方面可以根据 Java 代码生成相应的 JavaScript 代码供客户端调用,另一方面也可以直接在 Java 代码中调用 JavaScript 代码向客户端推送数据。 # Download URL http://directwebremoting.org/dwr/d

1. 简介

DWR(Direct Web Remoting) 是一个 Java 开源框架,一方面可以根据 Java 代码生成相应的 JavaScript 代码供客户端调用,另一方面也可以直接在 Java 代码中调用 JavaScript 代码向客户端推送数据。
# Download URL
http://directwebremoting.org/dwr/downloads/index.html
https://dist.apache.org/repos/dist/release/commons/logging/binaries/
# Documentation URL
http://directwebremoting.org/dwr/documentation/index.html
# 依赖 jar
commons-logging-1.1.3.jar
dwr.jar

2. JavaScript 调用 Java

2.1 编写 Java 代码

package org.demo.dwr.bean;
/**
 * bean - User
 * @author  
 * @date    2013-11-20
 * @file    org.demo.dwr.bean.User.java
 */
public class User {
    private String id;
    private String name;
    private String email;
    
    /**
     * toString
     */
    public String toString() {
    	StringBuilder sb = new StringBuilder();
    	sb.append('{');
    	sb.append("id:" + id).append(",");
    	sb.append("name:" + name).append(",");
    	sb.append("email:" + email);
    	sb.append('}');
    	return sb.toString();
    }

	public String getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public String getEmail() {
		return email;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setEmail(String email) {
		this.email = email;
	}
}
package org.demo.dwr.web;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.demo.dwr.bean.User;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;

/**
 * dwr - UserDwr
 * @author  
 * @date    2013-11-20
 * @file    org.demo.dwr.web.UserDwr.java
 */
public class UserDwr {

	private static UserDwr instance = new UserDwr();
	private Map<String,User> allUsers = new HashMap<String,User>();
	
	/**
	 * 当 dwr.xml 中 creator 的类型为 static 时,需要调用此方法获取一个实例
	 * @return
	 */
	public static UserDwr getInstance() {
		return instance;
	}
	
	/**
	 * 增加用户
	 * @param user
	 * @return
	 */
	public String addUser(User user) {
		allUsers.put(user.getId(),user);
		return "success";
	}
	
	/**
	 * 根据 id 查询用户
	 * @param id
	 * @return
	 */
	public String getUser(String id) {
		User user = allUsers.get(id);
		if (user == null) {
			return "User not found - [id: " + id + "]";
		}
		return user.toString();
	}
	
	/**
	 * 需要访问 request,response,session 等HTTP Servlet对象时只需要在参数列表中声明一下即可
	 * @param param1
	 * @param req
	 * @param resp
	 * @param session
	 */
	public void showServletObjects(
			String param1,HttpServletRequest req,HttpServletResponse resp,HttpSession session) {
		System.out.println("param1   = " + param1);
		System.out.println("request  = " + req);
		System.out.println("response = " + resp);
		System.out.println("session  = " + session);
		
		// 也可以通过下面这种方式获取HTTP Servlet对象
		WebContext ctx = WebContextFactory.get();
		System.out.println("request  = " + ctx.getHttpServletRequest());
	}
}
2.2 修改 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" 
  xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="
    http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>DwrTest</display-name>
    
	<servlet>
		<servlet-name>dwr-invoker</servlet-name>
		<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>dwr-invoker</servlet-name>
		<url-pattern>/dwr/*</url-pattern>
	</servlet-mapping>
	
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>
2.3 编写 WEB-INF/dwr.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
    "http://directwebremoting.org/schema/dwr30.dtd">
<dwr>
    
    <allow>
        <!-- 定义需要暴露给前台的 Java 类 -->
        <create creator="static" javascript="UserDwr">
            <param name="class" value="org.demo.dwr.web.UserDwr" />
        </create>
        
        <!-- 定义需要进行转换的 Java Bean -->
        <convert converter="bean" match="org.demo.dwr.bean.*" />
    </allow>
    
</dwr>
2.4 编写 index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>DWR - Test</title>

<!-- 引入与 DWR 相关的 js 文件 -->
<script src='dwr/engine.js'></script>
<script src='dwr/util.js'></script>
<script src='dwr/interface/UserDwr.js'></script>

</head>
<body>
  
  <div>
      <input type="button" value="addUser" onclick="addUser()" />
      <input type="button" value="getUser" onclick="getUser()" />
      <input type="button" value="showServletObjects" onclick="showServletObjects()" />
  </div>
  <div id="result"></div>
  
</body>
<script type="text/javascript">
/**
 * 增加用户
 */
function addUser() {
	var user = {
	    id : '100',name : 'zhangsan',email : 'zhangsan@163.com'
    };
	UserDwr.addUser(user,{
        callback: function(retVal) {
            document.getElementById('result').innerHTML += '<br/>' + retVal; 
        },timeout: 3000,errorHandler: function(errorMsg) { 
            alert('Error Msg : ' + errorMsg); 
        }
    });
}
/**
 * 查询用户
 */
function getUser() {
	UserDwr.getUser('100',errorHandler: function(errorMsg) { 
            alert('Error Msg : ' + errorMsg); 
        }
    });
}
/**
 * 访问 HTTP Servlet 对象
 */
function showServletObjects() {
	UserDwr.showServletObjects('101');
}
</script>
</html>
2.5 测试

3. Java 调用 JavaScript
3.1 编写Java代码
package org.demo.dwr.web;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.extend.ScriptSessionManager;

/**
 * dwr - ServerStatusDwr
 * @author  
 * @date    2013-11-20
 * @file    org.demo.dwr.web.ServerStatusDwr.java
 */
public class ServerStatusDwr implements Runnable {

	private static ServerStatusDwr instance = new ServerStatusDwr();
	
	public static ServerStatusDwr getInstance() {
		return instance;
	}
	
	public ServerStatusDwr() {
		ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
		threadPool.scheduleWithFixedDelay(this,10,TimeUnit.SECONDS);
	}
	
	@Override
	public void run() {
		ServerContext ctx = ServerContextFactory.get();
		if (ctx == null) {
			return;
		}
		
		SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
		String currentTime = format.format(new Date());
		
		// 在非 DWR 线程中向前台推送数据
		ScriptBuffer script = new ScriptBuffer();
		script.appendCall("callback_refreshServerTime",currentTime);
		ScriptSessionManager manager = ctx.getContainer().getBean(ScriptSessionManager.class);
		Iterator<ScriptSession> it = manager.getAllScriptSessions().iterator();
		ScriptSession session = null;
		while (it.hasNext()) {
			session = it.next();
			session.addScript(script);
		}
	}
	
	public void refreshServerTime() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String currentTime = format.format(new Date());
		
		// 在 DWR 线程中向前台推送数据
		ScriptBuffer script = new ScriptBuffer();
		script.appendCall("callback_refreshServerTime",currentTime);
		WebContext ctx = WebContextFactory.get();
		ScriptSession session = ctx.getScriptSession();
		session.addScript(script);
	}
	
	public String echo(String value) {
		return "echo " + value;
	}
}
# 修改 WEB-INF/dwr.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
    "http://directwebremoting.org/schema/dwr30.dtd">
<dwr>
    
    <allow>
        <!-- 定义需要暴露给前台的 Java 类 -->
        <create creator="static" javascript="UserDwr">
            <param name="class" value="org.demo.dwr.web.UserDwr" />
        </create>
        <create creator="static" javascript="ServerStatusDwr">
            <param name="class" value="org.demo.dwr.web.ServerStatusDwr" />
            <include method="refreshServerTime"/>
            <include method="echo"/>
        </create>
        
        <!-- 定义需要进行转换的 Java Bean -->
        <convert converter="bean" match="org.demo.dwr.bean.*" />
    </allow>
    
</dwr>
# 编写 status.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>DWR - Test</title>

<!-- 引入与 DWR 相关的 js 文件 -->
<script src='dwr/engine.js'></script>
<script src='dwr/util.js'></script>
<script src='dwr/interface/ServerStatusDwr.js'></script>

</head>
<body>
  
  <input type="button" value="echo" onclick="echo()" />
  <input type="button" value="refresh" onclick="refreshServerTime()" />
  <div id="result"></div>
  
</body>
<script type="text/javascript">
// 采用主动模式时需要去掉下面的注释
// dwr.engine.setActiveReverseAjax(true);
// dwr.engine.setNotifyServerOnPageUnload(true);
function echo() {
    ServerStatusDwr.echo('HelloWorld',{
        async: false,callback: function(retVal) {
            document.getElementById('result').innerHTML += '<br/>' + retVal;
        }
    });
}
function refreshServerTime() {
    ServerStatusDwr.refreshServerTime();
}
function callback_refreshServerTime(retVal) {
    document.getElementById('result').innerHTML += '<br/>' + retVal;
}
</script>
</html>
3.2 被动模式
采用被动模式时,当服务端需要向客户端推送数据时,DWR会先将数据缓存起来,等下次有客户端请求过来时,再将需要推送的数据附加在这次请求的结果中,一起返回给客户端。
采用被动模式时,不需要做什么特殊配置,因为DWR默认就是被动模式。


3.3 主动模式
采用主动模式时,是由客户端主动发起请求从服务端获取需要推送的数据,而不是将这些数据附加在其他请求的结果中进行返回。

# 采用主动模式时需要在 web.xml 中加入参数 activeReverseAjaxEnabled
# 同时在页面中需要加入 dwr.engine.setActiveReverseAjax(true);
	<servlet>
		<servlet-name>dwr-invoker</servlet-name>
		<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
		<init-param>
		    <param-name>activeReverseAjaxEnabled</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>
<script type="text/javascript">
// 采用主动模式时需要去掉下面的注释
dwr.engine.setActiveReverseAjax(true);
dwr.engine.setNotifyServerOnPageUnload(true);
// ...
</script>
4. 同步异步
DWR默认是异步调用,如果要修改成同步调用,有以下两种方法可以选择:
# 修改全局配置,将所有方法的调用模式都修改成同步
dwr.engine.setAsync(false);
# 修改局部配置,将当前方法的调用模式修改成同步
Remote.method(params,{
    async: false,callback: function(retVal){
        // ... 
    }
});
5. 错误处理
DWR中的错误处理也有两种:全局配置和局部配置
# 全局配置
dwr.engine.setErrorHandler(function(errorMsg,exception) {
    var info = 'Error: ' + errorMsg 
             + ' - Details: ' + dwr.util.toDescriptiveString(exception,2);
    alert(info);
});
# 局部配置
Remote.method(params,{
    callback: function(retVal) {
        // ... 
    },errorHandler: function(errorMsg,exception) {
        var info = 'Error: ' + errorMsg 
                 + ' - Details: ' + dwr.util.toDescriptiveString(exception,2);
        alert(info);
    }
});
6. 压缩 js
如果需要将DWR自动生成的 js 文件进行压缩处理,只需要在 WEB-INF/lib 目录中加入yuicompressor-2.4.8.jar 即可
# Download URL
https://github.com/yui/yuicompressor/releases
7. DWR-Spring
7.1 依赖 jar
spring-aop-3.2.5.RELEASE.jar
spring-beans-3.2.5.RELEASE.jar
spring-context-3.2.5.RELEASE.jar
spring-core-3.2.5.RELEASE.jar
spring-expression-3.2.5.RELEASE.jar
spring-web-3.2.5.RELEASE.jar
# Download URL
http://repo.spring.io/simple/libs-release-local/org/springframework/spring/3.2.5.RELEASE/
7.2 修改 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" 
  xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="
    http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>DwrTest</display-name>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:beans.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
	<servlet>
		<servlet-name>dwr-invoker</servlet-name>
		<servlet-class>org.directwebremoting.spring.DwrSpringServlet</servlet-class>
		<init-param>
		    <param-name>activeReverseAjaxEnabled</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>
	
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>
7.3 编写 src/beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
    xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.directwebremoting.org/schema/spring-dwr
       http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd" >
    
    <!-- 自动扫描需要暴露给前台的 Java 类 -->
    <!-- Allow DWR to scan the classpath,detect beans annotated with -->
    <!-- @RemoteProxy & @RemoteMethod and register the beans and Creator proxies for them. -->
    <dwr:annotation-scan base-package="org.demo.dwr.web" scanRemoteProxy="true"/>
    
    <!-- 自动扫描需要进行转换的 Java Bean -->
    <dwr:configuration>
        <dwr:convert type="bean" class="org.demo.dwr.bean.*" />
    </dwr:configuration>
    
</beans>
7.4 修改 Java 类
# 在需要暴露给前台的 Java 类上添加 @RemoteProxy 注解
# 在需要暴露给前台的 Java 方法上添加 @RemoteMethod 注解
package org.demo.dwr.web;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.demo.dwr.bean.User;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;

/**
 * dwr - UserDwr
 * @author  
 * @date    2013-11-20
 * @file    org.demo.dwr.web.UserDwr.java
 */
@RemoteProxy
public class UserDwr {
    
	private Map<String,User>();
	
	/**
	 * 增加用户
	 * @param user
	 * @return
	 */
	@RemoteMethod
	public String addUser(User user) {
		allUsers.put(user.getId(),user);
		return "success";
	}
	
	/**
	 * 根据 id 查询用户
	 * @param id
	 * @return
	 */
	@RemoteMethod
	public String getUser(String id) {
		User user = allUsers.get(id);
		if (user == null) {
			return "User not found - [id: " + id + "]";
		}
		return user.toString();
	}
	
	/**
	 * 需要访问 request,session 等HTTP Servlet对象时只需要在参数列表中声明一下即可
	 * @param param1
	 * @param req
	 * @param resp
	 * @param session
	 */
	@RemoteMethod
	public void showServletObjects(
			String param1,HttpSession session) {
		System.out.println("param1   = " + param1);
		System.out.println("request  = " + req);
		System.out.println("response = " + resp);
		System.out.println("session  = " + session);
		
		// 也可以通过下面这种方式获取HTTP Servlet对象
		WebContext ctx = WebContextFactory.get();
		System.out.println("request  = " + ctx.getHttpServletRequest());
	}
}
package org.demo.dwr.web;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.directwebremoting.extend.ScriptSessionManager;

/**
 * dwr - ServerStatusDwr
 * @author  
 * @date    2013-11-20
 * @file    org.demo.dwr.web.ServerStatusDwr.java
 */
@RemoteProxy
public class ServerStatusDwr implements Runnable {
	
	public ServerStatusDwr() {
		ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
		threadPool.scheduleWithFixedDelay(this,currentTime);
		ScriptSessionManager manager = ctx.getContainer().getBean(ScriptSessionManager.class);
		Iterator<ScriptSession> it = manager.getAllScriptSessions().iterator();
		ScriptSession session = null;
		while (it.hasNext()) {
			session = it.next();
			session.addScript(script);
		}
	}
	
	@RemoteMethod
	public void refreshServerTime() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String currentTime = format.format(new Date());
		
		// 在 DWR 线程中向前台推送数据
		ScriptBuffer script = new ScriptBuffer();
		script.appendCall("callback_refreshServerTime",currentTime);
		WebContext ctx = WebContextFactory.get();
		ScriptSession session = ctx.getScriptSession();
		session.addScript(script);
	}
	
	@RemoteMethod
	public String echo(String value) {
		return "echo " + value;
	}
}
# DWR上传下载文件
http://directwebremoting.org/dwr-demo/simple/upload.html
http://directwebremoting.org/dwr-demo/simple/download.html
http://directwebremoting.org/dwr/introduction/tutorials.html
# DWR Filter
package org.demo.dwr.web;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.directwebremoting.AjaxFilter;
import org.directwebremoting.AjaxFilterChain;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.annotations.GlobalFilter;

/**
 * filter - DWR filter
 * @author  
 * @date    2013-11-20
 * @file    org.demo.dwr.web.DwrParamFilter.java
 */
@GlobalFilter
public class DwrParamFilter implements AjaxFilter {

	public DwrParamFilter() {
	}

	@Override
	public Object doFilter(Object obj,Method method,Object[] params,AjaxFilterChain chain) throws Exception {
		
		WebContext ctx = WebContextFactory.get();
		HttpServletRequest req = ctx.getHttpServletRequest();
		
		String clientIp = req.getRemoteHost();
		String uri = req.getRequestURI();
		System.out.println("ip     = " + clientIp);
		System.out.println("uri    = " + uri);
		System.out.println("obj    = " + obj);
		System.out.println("method = " + method);
		System.out.println("params = " + params);
		
		// invoke next filter
		return chain.doFilter(obj,method,params);
	}
}
// END

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读