dwr(Direct Web Remoting)官网
官网github代码库地址
官网demo(war包,内有源码)
java推送信息给浏览器,就是浏览器有个轮寻的连接(定时发请求查询),或者长http,websocket连接来实现。
dwr的三种Reverse Ajax推送消息的方式 Piggyback, Polling and Comet
polling 就是【隔一段时间】向服务器发送一请求来检查服务端是否有数据更新
comet 就是一个长http请求,在请求期间服务端可以向客户端推送数据,但是这种做法要求服务器和浏览器【长期建立】一个通信通道,而且效率很低
piggyback 就是服务端的更新数据都在排队等待,等到【下一次有请求】过来,那么这些等待更新数据就伴随这次请求一起发送到浏览器
dwr的js调用java方法的部分就不看了,就是普通的调用请求返回结果,看起来就像js直接调用java。主要是使用dwr的reverse-ajax功能,来【方便快速实现】java【推送】给浏览器信息,实现web网页的实时更新功能。
dwr项目的整体配置过程
- 配置web.xml的servlet(DwrServlet重要的是各种参数init-param,DwrListener)
- 配置dwr.xml,推送处理类绑定,js方法与java类,与web.xml同级目录
- java类
- web页面,需要加载engine.js,util.js,dwr.xml中绑定的java类对应的js。【都是访问地址,dwr会自动生成】
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="dwr">
<display-name>DWR (Direct Web Remoting)</display-name>
<description>A Simple Demo DWR</description>
<listener>
<listener-class>org.directwebremoting.servlet.DwrListener</listener-class>
</listener>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<description>Direct Web Remoter Servlet</description>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>fileUploadMaxBytes</param-name>
<param-value>25000</param-value>
</init-param>
<!-- This should NEVER be present in live -->
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>accessLogLevel</param-name>
<param-value>runtimeexception</param-value>
</init-param>
<!-- Remove this unless you want to use active reverse ajax -->
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- By default DWR creates application scope objects when they are first
used. This creates them when the app-server is started -->
<init-param>
<param-name>initApplicationScopeCreatorsAtStartup</param-name>
<param-value>true</param-value>
</init-param>
<!-- WARNING: allowing JSON-RPC connections bypasses much of the security
protection that DWR gives you. Take this out if security is important -->
<init-param>
<param-name>jsonRpcEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- WARNING: allowing JSONP connections bypasses much of the security
protection that DWR gives you. Take this out if security is important -->
<init-param>
<param-name>jsonpEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- data: URLs are good for small images, but are slower, and could OOM for
larger images. Leave this out (or keep 'false') for anything but small images -->
<init-param>
<param-name>preferDataUrlSchema</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--推送路径与自动生成js-->
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<!--模拟java推送,访问后启动数据推送-->
<servlet>
<servlet-name>mydwr</servlet-name>
<servlet-class>dwr.Test</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mydwr</servlet-name>
<url-pattern>/mydwr.do</url-pattern>
</servlet-mapping>
</web-app>
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>
<create creator="new" scope="application" javascript="dwrpush">
<param name="class" value="dwr.Mydwr"/>
</create>
</allow>
</dwr>
Mydwr.java
package dwr;
import org.directwebremoting.Browser;
import org.directwebremoting.ScriptSessions;
public class Mydwr {
public static void sendMsg(final String html,final String msg){
Browser.withPage(html, new Runnable() {
@Override
public void run() {
//dealDwrData是mydwr.html页面定义好的处理推送数据js方法名
ScriptSessions.addFunctionCall("dealDwrData",msg);
}
});
}
}
Test.java 模拟java有数据需要推送到前端web页面
package dwr;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Test extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
while (true){
try{
Thread.sleep(3000);
System.out.println("mydwr start");
//向哪个页面推送数据,实现任意页面推送
Mydwr.sendMsg("/dwrtest/mydwr.html","hello");
}catch (Exception e){
e.printStackTrace();
}
}
}
}
mydwr.html 需要推送的页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--dwr自动生成-->
<script type='text/javascript' src='dwr/engine.js'></script>
<!--dwr自动生成-->
<script type='text/javascript' src='dwr/util.js'></script>
<!--dwr.xml中create的javascript属性,指定js文件名称-->
<script type='text/javascript' src='dwr/interface/dwrpush.js'></script>
<script>
window.onload = function(){
dwr.engine.setActiveReverseAjax(true);
dwr.engine.setErrorHandler(errorHandler);
dwr.engine.setPollStatusHandler(updatePollStatus);
}
function errorHandler(message, ex){
dwr.util.setValue("error", "<font color='red'>Cannot connect to server. Initializing retry logic.</font>", {
escapeHtml: false
});
setTimeout(function(){
dwr.util.setValue("error", "");
}, 5000)
}
function updatePollStatus(pollStatus){
dwr.util.setValue("pollStatus", pollStatus ? "<font color='green'>Online</font>" : "<font color='red'>Offline</font>", {
escapeHtml: false
});
}
//处理推送的数据,更新页面
function dealDwrData(data) {
console.log(data);
}
</script>
<title>mydwr</title>
</head>
<body>
检测服务器是否连接,会自动重连
Server status: <span id="pollStatus"></span>
<div id="error"></div>
</body>
</html>
WEB-INF/lib 下需要的jar包
commons-fileupload-1.2.jar
commons-io-1.3.1.jar
commons-logging-1.0.4.jar
dwr.jar
itext-2.0.6.jar
jakarta-oro-2.0.8.jar
log4j-1.2.12.jar
配置好tomcat项目,启动(项目名dwrtest)
访问http://localhost:8081/dwrtest/mydwr.html 看看js是否加载,路径对不对
访问http://localhost:8081/dwrtest/mydwr.do 启动推送 ,看到mydwr.html的控制台输出