<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>Chat Room</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!-- DWR 核心腳本 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/dwr/engine.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/dwr/util.js"></script>
<!-- 服務端暴露介面的客戶端 Stub -->
<script type="text/javascript" src="${pageContext.request.contextPath}/dwr/interface/ChatService.js"></script>
<script type="text/javascript">
// 發送消息
function send() {
var time = new Date();
var content = dwr.util.getValue("content");
var name = dwr.util.getValue("userName");
var info = encodeURI(encodeURI(name + " say:\n" + content));
var msg = {"msg": info, "time": time};
dwr.util.setValue("content", ""); // 清空輸入框
if (content) {
ChatService.sendMessage(msg); // 異步調用服務端
} else {
alert("發送內容不能為空!");
}
}
// 接收服務端推送 (由 ChatMessageClient.onApplicationEvent 觸發)
function showMessage(data) {
var message = decodeURI(decodeURI(data.msg));
var text = dwr.util.getValue("info");
if (text) {
dwr.util.setValue("info", text + "\n" + data.time + " " + message);
} else {
dwr.util.setValue("info", data.time + " " + message);
}
}
</script>
</head>
<body onload="dwr.engine.setActiveReverseAjax(true);">
<textarea rows="20" cols="60" id="info" readonly="readonly"></textarea>
<hr/>
暱稱:<input type="text" id="userName"/><br/>
消息:<textarea rows="5" cols="30" id="content"></textarea>
<input type="button" value=" Send " onclick="send()" style="height: 85px; width: 85px;"/>
</body>
</html>
engine.js (引擎)、util.js (DOM 工具)、interface/ChatService.js (服務 Stub);body onload 啟用 dwr.engine.setActiveReverseAjax(true) —— 開啟反向 AJAX (Comet) 連接,否則服務端無法主動推送;send() 組裝 {msg, time} 對象,調用 ChatService.sendMessage() (異步非阻塞);showMessage(data) 為服務端 ChatMessageClient 回調的客戶端入口,負責解碼並追加顯示;encodeURI/decodeURI 處理中文傳輸編碼問題 (現代專案建議全鏈路 UTF-8 + 設定 DWR 編碼過濾器)。
系列完結。完整項目結構:
web.xml(DWR Servlet + Spring) →dwr.xml(服務暴露) →applicationContext-beans.xml(Bean 註冊) → 領域模型/事件/服務/監聽器 →chat.jsp前端。生產建議搭配 Jetty 等支援 Continuation 的容器以提升 Comet 並發擴展性。