首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2EE

Spring + DWR Comet 實現無刷新多人聊天室(四):監聽器實現與 Spring/DWR 容器整合配置

     編輯:J2EE

ChatMessageClient:Spring ApplicationListener 監聽業務事件,推送至 DWR ScriptSession

package com.hoo.chat;

import java.util.Collection;
import java.util.Date;
import javax.servlet.ServletContext;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.web.context.ServletContextAware;
import com.hoo.entity.Message;

@SuppressWarnings("unchecked")
public class ChatMessageClient implements ApplicationListener, ServletContextAware {

    private ServletContext ctx;

    public void setServletContext(ServletContext ctx) {
        this.ctx = ctx;
    }

    @SuppressWarnings("deprecation")
    public void onApplicationEvent(ApplicationEvent event) {
        // 僅處理 ChatMessageEvent
        if (event instanceof ChatMessageEvent) {
            Message msg = (Message) event.getSource();
            ServerContext context = ServerContextFactory.get();
            // 獲取所有連接 chat.jsp 的 ScriptSession
            Collection sessions = context.getScriptSessionsByPage(ctx.getContextPath() + "/chat.jsp");
            for (ScriptSession session : sessions) {
                ScriptBuffer sb = new ScriptBuffer();
                Date time = msg.getTime();
                String s = time.getYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate() + " "
                        + time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds();
                // 構造 JavaScript 調用:showMessage({msg: '...', time: '...'})
                sb.appendScript("showMessage({msg: '")
                  .appendScript(msg.getMsg())
                  .appendScript("', time: '")
                  .appendScript(s)
                  .appendScript("'})");
                System.out.println(sb.toString());
                // 向瀏覽器推送腳本執行
                session.addScript(sb);
            }
        }
    }
}

核心流程解析

  1. 實現 ApplicationListener → 容器發布事件時自動回調 onApplicationEvent;
  2. 實現 ServletContextAware → 獲取 ServletContext 以構建頁面路徑;
  3. instanceof ChatMessageEvent 過濾業務事件;
  4. 透過 ServerContextFactory.get() 獲取 DWR 服務端上下文;
  5. getScriptSessionsByPage("/chat.jsp") 精準定位所有在線聊天頁面會話;
  6. 構造 ScriptBuffer → 生成調用客戶端 showMessage(data) 的 JS 代碼;
  7. session.addScript(sb) 將腳本推送至瀏覽器執行 (Comet 長連接通道)。

Spring 容器 Bean 註冊 applicationContext-beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
       xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="https://www.springframework.org/schema/beans
                           https://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="chatService" class="com.hoo.chat.ChatService"/>
    <bean id="chatMessageClient" class="com.hoo.chat.ChatMessageClient"/>

</beans>

DWR 配置 dwr.xml:暴露服務與類型轉換

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"
        "https://getahead.org/dwr/dwr30.dtd">
<dwr>
    <allow>
        <!-- Message 實體轉換器:僅序列化 msg、time 兩屬性 -->
        <convert match="com.hoo.entity.Message" converter="bean">
            <param name="include" value="msg,time"/>
        </convert>

        <!-- 以 Spring 容器創建 ChatService,暴露為 JavaScript ChatService -->
        <create creator="spring" javascript="ChatService">
            <param name="beanName" value="chatService"/>
        </create>
    </allow>
</dwr>

配置要點

  • creator="spring":告訴 DWR 從 Spring 容器獲取 Bean,而非自行實例化;
  • beanName="chatService":對應 Spring Bean id;
  • convert match="...Message":自定義序列化策略,避免暴露敏感字段或循環引用;
  • include="msg,time":僅傳輸業務必需字段,減小網絡負載。

前置條件:web.xml 已配置 DwrListener、DwrServlet (含 pollAndCometEnabled=true)、ContextLoaderListener。詳細見系列第三篇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved