工作也已经有几年了, 最近突然心血来潮, 想写点技术博客,记录在工作和学习中碰到的一些问题,一方面方便自己以后查看,一方面也可以帮助下碰到同类问题的朋友们。 好了,闲话少说,进入第一篇博客的正文。
最近工作中有一个需求,需要开发一个类似QQ的即时聊天系统,不过要基于BS架构,上网搜索了下,JAVA中的COMET技术可以成为实现该需求的良好途径。
comet 【计】:基于 HTTP 长连接的“服务器推”技术,是一种新的 Web 应用架构。基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求。Comet 架构非常适合事件驱动的 Web 应用,以及对交互性和实时性要求很强的应用,如股票交易行情分析、聊天室和 Web 版在线游戏等。(百度百科)
现在网上有不少开源的comet框架,比如pushlet,dwr等, 当然, 你也可以自用用jquery甚至纯JS来实现。 我这里选用了dwr,毕竟是比较成熟的框架了,用起来可能可以比较顺手些。
简单介绍下DWR,DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJAX技术的网站。它可以允许在浏览器里的代码使用运行在WEB服务器上的JAVA函数,就像它就在浏览器里一样。(百度百科)
显然,楼主不方便把实际工作的代码放上来,这里就放一个简易的DEMO, DEMO实现了一些基本功能:
1. 前台调用后台的JAVA方法,并利用JAVA返回值执行回调函数。
2. 在后台中将数据发送至第二个页面,并调用该页面的JS方法。
3. 与SPRING的简单整合。
下面楼主把实现这个工程的步骤重复下。
第一步, 自然要先导入JAR包。 这个DEMO只需要DWR和SPRING2个JAR包,如需要可以在附件中下载(包含在DEMO的项目中)。
然后,配置WEB.xml文件,配置如下,功能基本已经写了注释,再补充一点,通过[项目地址]/dwr可以查看被dwr转化的类,可以点击进入测试页面,这样对于一些不知道怎么在实际页面中调用的初学者,可以查看源文件复制其代码。 在实际项目发布后将其设置为false,以避免用户进入此页面。
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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">
<servlet>
<!-- dwr配置 -->
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<description>打开debug可以通过[项目地址]/dwr查看被加载的类</description>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<description>使用服务器推技术(反转AJAX)</description>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<description>使用comet方式推送数据</description>
<param-name>pollAndCometEnabled</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>
<!-- Spring配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/bean.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
接下去是dwr的配置文件dwr.xml,将它放在web.xml的同一级即可。 这里是最简单的和spring的整合配置,如需更加复杂的功能,请自行搜索。
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
"http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
<allow>
<!-- 让dwr自动生成Controller.js文件 -->
<create creator="spring" javascript="Controller">
<param name="beanName" value="controller" />
</create>
<!-- 转化器,DWR对于自定义的BEAN需要转换,可以用*表示所有 -->
<convert match="songzl.message.User" converter="bean" />
</allow>
</dwr>
下面spring的配置文件 bean.xml. 根据web.xml中的配置,将其放入src的根目录下。配置很简单,就是设置一个自动加载的bean的范围, 当然你也可以用<bean id="XXX" class="XXX"> 这样来加载。
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-lazy-init="true" default-autowire="byName">
<!-- 扫描songzl.message包下的类 并将其自动加载为spring的bean -->
<context:component-scan base-package="songzl.message">
</context:component-scan>
</beans>
接下去2个JAVA类。 第一个user.java,一个放参数的javaben没什么可以多说
package songzl.message;
public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
第二个是控制类,Controller.java,也就是后台业务逻辑的主要实现类。 这里需要说下的是ScriptSession。ScriptSession是由DWR创建的,它用于保持长连接以管理页面。在JAVA中通过ServerContextFactory.get().getScriptSessionsByPage 来获取指定页面的ScriptSession以调用该页面的JS方法。关于ScriptSession后文还有一些补充。
package songzl.message;
import java.util.Collection;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContextFactory;
import org.springframework.stereotype.Component;
@Component
public class Controller {
public String getLoginUser(User user){
final String result = "name: "+user.getName()+"----password:"+user.getPassword();
System.out.println(result);
String recivePage = "/DwrTest/message/reciver.jsp"; //接收方的页面 /项目名/页面
Collection<ScriptSession> scss = ServerContextFactory.get().getScriptSessionsByPage(recivePage);//获取所有指定页面
for(ScriptSession ss : scss){
ss.addScript(new ScriptBuffer("reciverMes('"+result+"')")); //调用页面的JS方法
}
return result;
}
}
接下去是发送页面,sender.jsp。 要注意不要忘记导入engine.js和Controller.js。 其中Controller.js是DWR根据你的配置文件自动帮你生成的。
<%@ 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>数据发送页面</title>
<script type='text/javascript' src='/DwrTest/dwr/engine.js'></script>
<script type="text/javascript" src="/DwrTest/dwr/interface/Controller.js"></script>
<script type="text/javascript">
function submitLogin(){
var name=document.getElementById("name").value;
var password=document.getElementById("password").value;
var obj={name:name,password:password}; //obj需要在dwr.xml中配置conventer,字段名需要和class中的一致
//回调函数,返回JAVA方法中的返回值
Controller.getLoginUser(obj,function(data){
alert("返回的值是"+data);
})
}
</script>
</head>
<body>
账号 :<input type="text" id="name"/>
密码 : <input type="text" id="password"/>
<input type="submit" value="提交" onclick="submitLogin()"/>
</body>
</html>
最后是接收的页面。 reciver.jsp。 要注意的是一定不要忘记加上onload="dwr.engine.setActiveReverseAjax(true)" 楼主一开始就是忘了这句。 结果怎么也调试不出来。 蛋疼呐
<%@ 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>数据接受页面</title>
<script type='text/javascript' src='/DwrTest/dwr/engine.js'></script>
<script type="text/javascript">
function reciverMes(mes){
alert(mes);
}
</script>
</head>
<body onload="dwr.engine.setActiveReverseAjax(true)">
<font size='5'>当发送页面点击发送信息, 本地可以立即接受到发来的消息</font>
</body>
</html>
这样这个工程基本就定型了。 打开http://localhost:8080/DwrTest/message/sender.jsp和http://localhost:8080/DwrTest/message/reciver.jsp两个页面。 在第一个页面的输入框中随便填一点值,点击提交。 第一个页面会执行其回调函数。 第二个页面会执行controller中的方法。 (注意 为示区别 2个页面alert的值是不一样的)
最后,对ScriptSession作一点补充。"当我们访问一个页面的时候,如果是第一次访问,就会创建一个新的HttpSession,之后再访问的时候,就会保持当前的Session,即使是刷新,也能保持当前的HttpSession。 但是,ScriptSession不同,第一次访问,会创建一个ScriptSession,但是,如果你刷新,就会创建一个新的ScriptSession". 通过这段描述不难发现,如果用户多次刷新页面,将产生无数个无用的ScriptSession, 占了内存不说还会影响后来用户的链接。
怎么解决呢?DWR3 提供了ScriptSessionManager 这个接口来管理ScriptSession。 大家可以写一个类 复写DefaultScriptSessionManager这个方法,在其中捕获无用的scriptSession,并调用scriptSession.invalidate()将其无效化。 然后在WEB.XML的DWR的servlet配置中加入下面的代码:
<init-param>
<param-name>
org.directwebremoting.extend.ScriptSessionManager
</param-name>
<param-value>
你的实现类(X.X.XXX)
</param-value>
</init-param>
具体实现代码就不贴了,可以通过搜索引擎搜索下。 并不是很复杂。
分享到:
相关推荐
**DWR(Direct Web Remoting)与Spring框架的整合** DWR是一款开源的Java库,它允许在浏览器和服务器之间进行动态、实时的双向通信,实现了JavaScript与Java之间的远程调用。Spring则是一个广泛使用的Java企业级...
**DWR整合Spring MVC**是将Direct Web Remoting (DWR)框架与Spring MVC结合使用,以实现前端JSP页面直接调用后端Java方法的功能。这种整合方式极大地提高了Web应用的交互性和实时性,降低了数据传输的复杂性。本文将...
4. **安全性**:整合DWR和Spring可以利用Spring的安全框架,对远程方法调用进行权限控制,增强应用的安全性。 **DWR与Struts2的整合**包括: 1. **Action与DWR交互**:Struts2的Action类可以调用DWR生成的...
通过阅读和运行Demo,你可以理解DWR的工作原理,学习如何设置和调用后台方法,以及如何实现消息推送。 总结起来,这个主题涵盖了使用DWR进行JavaScript与Java后台交互的基本步骤,以及利用DWR的Push功能实现消息...
Spring提供了强大的依赖注入、事务管理以及AOP(面向切面编程)等功能,而DWR则允许在浏览器端直接调用服务器端的Java方法,实现页面的实时更新。将两者整合可以提升Web应用的交互性和用户体验。 **Spring框架** ...
《DWR2.0与Spring2.0整合详解》 Direct Web Remoting (DWR) 是一个开源的Java库,它允许在JavaScript和Java之间进行实时的、安全的、跨域的通信,使得Web应用程序可以像桌面应用一样具有丰富的用户交互体验。DWR2.0...
整合Spring和DWR可以使Web应用更加强大且易于维护,通过上述步骤和示例,你应该能理解如何在Spring2中整合DWR并把DWR配置写入Spring的配置文件中。在实际项目中,根据具体需求进行调整和优化,以达到最佳效果。
通过以上四个步骤,你就成功地将Spring与DWR进行了整合,使得后台服务可以通过Ajax在前端页面上实时展现,提高了Web应用的交互性。在实际开发中,还需要注意处理异常、安全性以及性能优化等问题。
**Spring+DWR整合项目详解** Spring框架是Java企业级应用开发中的主流框架,它提供了依赖注入、AOP(面向切面编程)、MVC(模型-视图-控制器)等核心功能,极大地简化了开发流程。DWR(Direct Web Remoting)则是一...
### Spring使用Annotation整合DWR知识点解析 #### 一、概览 在现代Web开发中,Direct Web Remoting(简称DWR)是一种简化Ajax应用开发的技术,它允许JavaScript直接调用服务器端的Java方法,而无需编写复杂的XML...
整合DWR和Spring的主要目标是利用Spring的管理能力来处理DWR的bean,同时利用DWR的动态JavaScript生成能力来简化客户端的Ajax调用。 1. **DWR的配置**: - 在DWR 2.0中,我们需要在Web应用的`WEB-INF/dwr.xml`配置...
4. **前后端交互**:前端JavaScript通过DWR调用后端的Java方法,这些方法由Spring管理并可能涉及Hibernate操作。数据在服务器和客户端之间以JSON格式传递,实现了高效的数据交换。 **项目结构** 从压缩包文件名"DWR...
**DWR-Spring Demo** 是一个结合了Direct Web Remoting (DWR) 和 Spring 框架的示例项目,旨在展示如何在Web应用程序中整合这两个技术,实现异步JavaScript和XML(AJAX)功能。DWR允许JavaScript与服务器端Java代码...
下面将详细阐述DWR的工作原理、配置过程以及如何使用DWR实现JS调用Java后台方法。 1. **DWR概述** DWR的核心功能是提供一种安全、高效的远程方法调用机制,通过HTTP协议在客户端(浏览器)和服务器之间传递数据。...
Spring还提供了对其他框架的集成支持,如数据库访问、事务管理以及与Struts2和DWR的整合。 Struts2是一个基于MVC设计模式的Java Web框架,用于构建可维护、可扩展的应用程序。它提供了强大的动作类、拦截器、结果...
**DWR(Direct Web Remoting)前后台交互详解** DWR(Direct Web Remoting)是一种JavaScript库,它允许Web应用程序在客户端(浏览器)与服务器端(后台)之间进行实时的、安全的、跨域的双向通信。DWR使得开发者...
总的来说,通过注解的方式整合EXT、DWR、Spring和Hibernate,可以实现前端UI的动态渲染、后端数据的高效管理以及两者之间的无缝通信。这种整合方式减少了配置文件的复杂性,提高了代码的可读性和可维护性,同时增强...
本示例"ext-dwr-spring集成Demo"就是一种将三个重要技术组件——EXT、Direct Web Remoting (DWR) 和Spring框架融合的实践。EXT是一个强大的JavaScript库,用于构建富客户端BS(Browser-Server)架构的应用;DWR则...