dwr3与struts2整合,实现服务器端推送技术,实现多人聊天功能

本文介绍了如何将DWR3与Struts2进行整合,利用服务器端推送技术实现多人聊天功能。文章详细讲解了从添加jar包、配置web.xml和dwr.xml,解决过滤器冲突,到引入JavaScript文件,初始化页面,以及发送消息端的代码实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1,首先放入struts2和dwr的jar包,这个想必大家都知道了吧!

2,下面是web.xml的全部配置信息,因为当初是ssh2一起整合的,所以会有spring的配置信息,

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<!-- 整合Spring -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/applicationContext.xml</param-value>
	</context-param>


	<!-- 配置Spring的OpenSessionInViewFilter,以解决懒加载异常 -->
	<filter>
		<filter-name>OpenSessionInViewFilter</filter-name>
		<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>OpenSessionInViewFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- 配置Struts2的过滤器 -->
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>


	<!-- dwr相关配置 -->
	<servlet>
    <servlet-name>dwr-invoker</servlet-name>
    <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
    <init-param>
      <param-name>fileUploadMaxBytes</param-name>
      <param-value>25000</param-value>
    </init-param>
    <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>
    <init-param>
      <param-name>activeReverseAjaxEnabled</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>initApplicationScopeCreatorsAtStartup</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>jsonRpcEnabled</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>jsonpEnabled</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>preferDataUrlSchema</param-name>
      <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </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>

 

3,以下是dwr的全部配置信息 ,dwr.xml是放在WEB-INF下面,就是和web.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>  
		<!--new的意思是每次都实例化一个,javascript的意思就是代替-param中的value的简称,可以在js中直接可以用messgeService调用 
			cn.ittec.zfx.service.impl.MessageServiceImpl中的方法-->
		<create creator="new" javascript="messageService">  
		<param name="class" value="cn.ittec.zfx.service.impl.MessageServiceImpl"/>  
		</create>  
	</allow>  
</dwr>  

 

这里还需要注意一点 dwr的过滤器和struts2 的过滤器都过滤的是整个项目,所以会有冲突,所以要在struts.xml中配置一下来解决中途问题

<constant name="struts.action.excludePattern" value="/dwr/*"></constant>


 

 

4,接下来就是在接收推送消息的界面引入dwr的js

其中:engine.js和util.js是在dwr.jar包里面的,在项目的WebRoot下面是找不到的,如果你想看,可以到dwr.jar里面找,肯定有,然后还需要引入messageService.js

<script type="text/javascript" src="dwr/engine.js"></script>  
<script type="text/javascript" src="dwr/util.js"></script>  
<script type="text/javascript" src="dwr/interface/messageService.js"></script>


 

5,在接收推送消息的界面body里面初始化一些东西



 

	<script type="text/javascript">
		//页面加载完之后执行这个方法,与服务器建立长连接
		function unready(){
			//dwr.engine.setActiveReverseAjax(true);与服务器建立一个长连接,默认是false,如果是false连接会在5分钟后注销
			//onPageLoad会触发自己的一个方法
			dwr.engine.setActiveReverseAjax(true);
			dwr.engine.setNotifyServerOnPageUnload(true);
			onPageLoad();
		}
			
		/**
		 *	当打开此页面时,触发这个方法,与服务器建立一个长连接,随时推送服务器消息
		**/
		function onPageLoad(){
			//获取将要给哪个登录的id发送消息
			var sendId = document.getElementById("sendId").value;
			//****通过这个方法调用cn.ittec.zfx.service.impl.MessageServiceImpl中的onPageLoad方法
			messageService.onPageLoad(sendId);  
		}
</script>


 

6,下面是 onPageLoad 方法的说明(不用说明的都不用改,只要copy到你的项目就ok了,因为有些我也不是太懂,哈)

	public void onPageLoad(String sendId) {//sendId 打开的聊天窗口对应的User的id
		ScriptSession scriptSession = WebContextFactory.get()
				.getScriptSession();
		scriptSession.setAttribute(sendId, sendId);
		//DwrScriptSessionManagerUtil是自己写的一个类
		DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();
		try {
			dwrScriptSessionManagerUtil.init();
		} catch (ServletException e) {
			e.printStackTrace();
		}
	}

 

下面是DwrScriptSessionManagerUtil.java类的说明

package cn.ittec.zfx.util;

import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;

import org.directwebremoting.Container;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.event.ScriptSessionEvent;
import org.directwebremoting.event.ScriptSessionListener;
import org.directwebremoting.extend.ScriptSessionManager;
import org.directwebremoting.servlet.DwrServlet;

import cn.ittec.zfx.domain.User;

public class DwrScriptSessionManagerUtil extends DwrServlet {


	private static final long serialVersionUID = 1L;

	public void init() throws ServletException {
		Container container = ServerContextFactory.get().getContainer();
		ScriptSessionManager manager = container
				.getBean(ScriptSessionManager.class);
		ScriptSessionListener listener = new ScriptSessionListener() {
			public void sessionCreated(ScriptSessionEvent ev) {
				HttpSession session = WebContextFactory.get().getSession();
				//这里的意思是你放在session里用户的id
				User user = (User) session.getAttribute("user");
				String userId  = user.getId()+ "";
				//String userId = ZfxUtils.getUserFromSession().getId() + "";
				ev.getSession().setAttribute("userId", userId);
			}

			public void sessionDestroyed(ScriptSessionEvent ev) {
			}
		};
		manager.addScriptSessionListener(listener);
	}

}

 

 

7,到此接收端的一些操作就完成了,下面是发送信息端的代码。

当你点击发送按钮将推送信息的时候要用js触发这个方法

messageService.pushMessagee(id,name ,contextTwo);
 
下面是pushMessagee的代码:
public void pushMessagee(String userid,String name, String contextTwo) throws Exception {
		final String userId = userid;//接收端用户的id
  		final String userName = name;//发送端的name,告诉他是 谁谁谁发的,类似QQ
		final String autoMessage = contextTwo; //将要发送的内容
		Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
			public boolean match(ScriptSession session) {
				if (session.getAttribute("userId") == null){
					return false;
				}
				else{
					return (session.getAttribute("userId")).equals(userId);
				}
			}
		}, new Runnable() {
			private ScriptBuffer script = new ScriptBuffer();
			public void run() {
				//这里比较重要了。showMessage是接收页面js中的方法名,userName和antoMessage分别是方法的参数,信息全部发送过去了,接下来你要弹框还是写到页面就看你的需求了,
				script.appendCall("showMessage" ,userName, autoMessage);
				Collection<ScriptSession> sessions = Browser
						.getTargetSessions();
				for (ScriptSession scriptSession : sessions) {
					scriptSession.addScript(script);
				}
			}
		});

	}



8,至此全部搞定了,看似很简单,但是有些地方还是不太清楚,由于原项目不方便供给大家参考,如果大家还有什么不懂的,可以留言告诉我,我会尽力帮助大家,互相帮忙嘛!!

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值