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 代码向客户端推送数据。 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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |