人生,最宝贵的莫过于光阴。人生,最璀璨的莫过于事业。人生,最快乐的莫过于奋斗。
官网解释:DWR(Direct Web Remoting)是一个Java库,使服务器上的Java对象和JavaScript的浏览器进行交互并调用变得更简单。
DWR是一个Java框架,它是基于Ajax,用于实现浏览器(网页)和服务器(后台)更好的交互。DWR在使用过程中会自动生成javascript文件,调用Java对象,实现对象中的方法。
举一个简单的例子,如果用户在页面上要访问后台数据可以通过Ajax实现,但是如果要实现多个页面相互分享数据那就不能仅仅靠Ajax来实现了。因为Ajax只能有浏览器发起,服务端返回,没办法实现多个页面数据相互交流,而DWR可以实现把消息推送到其他页面。
下面以一个实现服务端向Web客服端推送消息的小案例,来说说DWR该如何搭建。
一、DWR安装(导包):dwr.jar+commons-logging.jar
DWR提供一个核心包dwr.jar,使用DWR必须将其导入工程。可以通过Maven导入:
<dependency>
<groupId>org.directwebremoting</groupId>
<artifactId>dwr</artifactId>
<version>3.0.2-RELEASE</version>
</dependency>
至于DWR官网提供的其他包,有需要在添加。除了dwr.jar之外还有添加另外DWR的依赖包commons-logging.jar。
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
二、配置web.xml,添加DwrServlet。
找到工程中web.xml,在其中添加新的
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<!-- 使用服务器反转AJAX -->
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- 是能够从其他域请求true:开启; false:关闭 -->
<init-param>
<param-name>crossDomainSessionSecurity</param-name>
<param-value>false</param-value>
</init-param>
<!-- 允许远程调用js -->
<init-param>
<param-name>allowScriptTagRemoting</param-name>
<param-value>true</param-value>
</init-param>
<!-- 开启Debug,可以查看Dwr相关方法 -->
<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>
这段部署描述告诉Web应用程序,全部以“/dwr/”起始的URL所指向的请求都交给org.directwebremoting.servlet.DwrServlet这个Java Servlet来处理。
DWR3.x版本,使用org.directwebremoting.servlet.DwrServlet。
DWR2.x版本,使用uk.ldt.getahead.dwr.DWRServlet。
三、设置dwr.xml配置文件
在{APPLICATION_WEB_HOME}/WEB-INF目录下创建dwr.xml部署描述文件。该文件与web.xml属于同一目录。
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
"http://getahead.org/dwr/dwr30.dtd">
<dwr>
<allow>
<create creator="new" javascript="DwrPush">
<param name="class" value="cc.dwr.test.DwrPush" />
</create>
</allow>
</dwr>
javascript="DwrPush"是指DWR生成的javascript文件名称,value="cc.dwr.test.DwrPush"是后台Java对象。到这里有人就奇怪了,这些东西有啥用?简单一点来说,就是网页通过DWR生成的DwrPush.js文件来执行cc.dwr.test.DwrPush类中的方法。
至于生成的DwrPush.js文件位置,默认它是在{APPLICATION_WEB_HOME}/dwr/DwrPush.js。
dwr.xml组成元素及其属性和用途,这里包括旧版本的一些属性,新版本有一些属性不在支持。
四、后台Java类书写(cc.dwr.test.DwrPush)
旧版本(2.x)调用方法,向所有用户发送消息
// 实现客户端发送过来的信息推送出去
// @param msg 客户端发送过来的消息
public void send(String msg) {
System.out.println(msg);
WebContext webContext = WebContextFactory.get();
Collection<ScriptSession> sessions = webContext.getAllScriptSessions();
/**
* 推送消息所要执行的业务逻辑
*/
// 构建发送所需的JS脚本
ScriptBuffer scriptBuffer = new ScriptBuffer();
// 调用客户端的js脚本函数
scriptBuffer.appendScript("revice(");
scriptBuffer.appendData(msg);
scriptBuffer.appendScript(")");
// 实现推送
// 为所有的用户服务
Util util = new Util(sessions);
util.addScript(scriptBuffer);
}
新版本(3.x)调用方法,向所有用户发送消息
// 实现客户端发送过来的信息推送出去
// @param msg 客户端发送过来的消息
public void send2(final String msg) {
System.out.println(msg);
Browser.withAllSessions(new Runnable() {
@Override
public void run() {
Collection<ScriptSession> sessions = Browser.getTargetSessions();
/**
* 推送消息所要执行的业务逻辑
*/
// 构建发送所需的JS脚本
ScriptBuffer scriptBuffer = new ScriptBuffer();
// 调用客户端的js脚本函数
scriptBuffer.appendCall("revice", msg);
// 遍历每一个ScriptSession
for (ScriptSession scriptSession : sessions) {
scriptSession.addScript(scriptBuffer);
}
}
});
}
新版本(3.x)调用方法,向特定用户发送消息(部分代码)
// 实现客户端发送过来的信息推送出去
// 实现精准推送
// @param msg 客户端发送过来的消息
public void send3(final String msg) {
System.out.println(msg);
// ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
// scriptSession.setAttribute(name, value);
Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
@Override
public boolean match(ScriptSession session) {
// 执行过滤操作,true允许,false不允许
return false;
}
}, new Runnable() {
// 执行推送消息
Collection<ScriptSession> sessions = Browser.getTargetSessions();
@Override
public void run() {
/**
* 推送消息所要执行的业务逻辑
*/
// 构建发送所需的JS脚本
ScriptBuffer scriptBuffer = new ScriptBuffer();
// 调用客户端的js脚本函数
scriptBuffer.appendCall("revice", msg);
// 遍历每一个ScriptSession
for (ScriptSession scriptSession : sessions) {
scriptSession.addScript(scriptBuffer);
}
}
});
}
五、网页(JSP)创建
(1)、导入js文件
<script type="text/javascript" src="<%=basePath%>dwr/engine.js"></script>
<script type="text/javascript" src="<%=basePath%>dwr/util.js"></script>
<script type="text/javascript" src="<%=basePath%>dwr/interface/DwrPush.js"></script>
engine.js、util.js是dwr.jar自动提供的,DwrPush.js是dwr自动生成的。注意路径的正确性。
(2)、书写js方法
<script type="text/javascript">
// dwr反转激活
dwr.engine.setActiveReverseAjax(true);
// 发送推送消息
function send() {
var msg = document.getElementById("msg").value;
alert(msg);
// DwrPush是在dwr.xml文件中声明的javascript属性
DwrPush.send2(msg);
}
// 接收推送消息
function revice(msg) {
alert(msg);
document.getElementById("send_content").innerHTML = msg;
}
</script>
注意:
dwr.engine.setActiveReverseAjax(true)实现dwr反转激活。
DwrPush.send2(msg);该方法是DwrPush.js文件中提供的,DwrPush.js文件是根据cc.dwr.test.DwrPush类生成,所以该类中的所有方法都是可以通过DwrPush.的形式进行引用。
revice(msg)接收消息的方法,由cc.dwr.test.DwrPush类中ScriptBuffer来确定。
本案例中写了一个send.jsp(发送页面)和一个revice.jsp(接收页面)。
send.jsp(发送页面)布局:
<body>
<center>
<p id="send_content"></p>
<input type="text" name="msg" id="msg" maxlength="50">
<input type="button" id="send" value="发送信息" onclick="send()">
</center>
</body>
revice.jsp(接收页面):
<script type="text/javascript" src="<%=basePath%>dwr/engine.js"></script>
<script type="text/javascript" src="<%=basePath%>dwr/util.js"></script>
<script type="text/javascript">
// dwr反转激活
dwr.engine.setActiveReverseAjax(true);
// 接收推送消息
function revice(msg) {
alert(msg);
document.getElementById("revice_content").innerHTML = msg;
}
</script>
<body>
<center>
<p id="revice_content"></p>
</center>
</body>
好,到这里就基本上完成,看看效果。
微信公众号:伴职创作