來寫個AJAX版的聊天室吧!先看看直接使用AJAX要如何做到,首先需要一個簡單的聊天室Servlet…
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 package onlyfun.caterpillar; import java.io.IOException;import java.io.PrintWriter;import java.util.LinkedList;import java.util.List; import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse; public class ChatRoomServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { private static LinkedList<Message> messages = new LinkedList<Message>(); public ChatRoomServlet() { super(); } private List<Message> addMessage(String text) { if (text != null && text.trim().length() > 0) { messages.addFirst(new Message(text)); while (messages.size() > 10) { messages.removeLast(); } } return messages; } private List<Message> getMessages() { return messages; } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Message> list = null; if("send".equals(request.getParameter("task"))) { list = addMessage(request.getParameter("msg")); } else if("query".equals(request.getParameter("task"))){ list = getMessages(); } PrintWriter out = response.getWriter(); response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); out.println("<response>"); for(int i = 0; i < list.size(); i++) { String msg = list.get(i).getText(); out.println("<message>" + msg + "</message>"); } out.println("</response>"); } }
Message物件如下…
1234567891011121314151617181920212223 package onlyfun.caterpillar; public class Message { private long id = System.currentTimeMillis(); private String text; public Message(String newtext) { text = newtext; if (text.length() > 256) { text = text.substring(0, 256); } text = text.replace('<', '['); text = text.replace('&', '_'); } public long getId() { return id; } public String getText() { return text; }}
Servlet接受訊息新增與查詢,判斷的方式是檢查請求參數task是send或query。
Servlet會以XML傳回目前List當中的訊息,客戶端可以查詢或插入新訊息時,取得目前List中的訊息,接著在web.xml中設定一下…
12345678910111213141516171819202122 <?xml version="1.0" encoding="UTF-8"?><web-app id="WebApp_ID" 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> <description> </description> <display-name> ChatRoomServlet</display-name> <servlet-name>ChatRoomServlet</servlet-name> <servlet-class> onlyfun.caterpillar.ChatRoomServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ChatRoomServlet</servlet-name> <url-pattern>/ChatRoomServlet</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app>
在網頁中,使用者可以在輸入訊息後按下按鈕送出資訊,並在XML回應取得時,將訊息以一列一列的表格方式顯示出來,另外還設定了週期性的輪詢,即使不輸入新訊息,也可以週期性的取得新的聊天訊息…
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=BIG5"><title>Chat Room</title> <script type="text/javascript">var xmlHttp; function createXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); }} function sendMessage() { var msg = document.getElementById("text").value; if(msg == "") { refreshMessage(); return; } var param = "task=send&msg=" + msg; ajaxRequest(param); document.getElementById("text").value = "";} function queryMessage() { var param = "task=query"; ajaxRequest(param);} function ajaxRequest(param) { var url = "ChatRoomServlet?timestamp" + new Date().getTime(); createXMLHttpRequest(); xmlHttp.onreadystatechange = refreshMessage; xmlHttp.open("POST", url, true); xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); xmlHttp.send(param);} function refreshMessage() { if(xmlHttp.readyState == 4) { if(xmlHttp.status == 200) { var messages = xmlHttp.responseXML.getElementsByTagName("message"); var table_body = document.getElementById("dynamicUpdateArea"); var length = table_body.childNodes.length; for (var i = 0; i < length; i++) { table_body.removeChild(table_body.childNodes[0]); } var length = messages.length; for(var i = length - 1; i >= 0 ; i--) { var message = messages[i].firstChild.data; var row = createRow(message); table_body.appendChild(row); } setTimeout("queryMessage()", 2000); } }} function createRow(message) { var row = document.createElement("tr"); var cell = document.createElement("td"); var cell_data = document.createTextNode(message); cell.appendChild(cell_data); row.appendChild(cell); return row;} </script> </head><body> <p> Your Message: <input id="text"/> <input type="button" value="Send" onclick="sendMessage()"/></p> <p>Messages:</p> <table align="left"> <tbody id="dynamicUpdateArea"></tbody> </table> </body></html>
簡單抓個畫面…
直接用AJAX,後端用JSP/Servlet,您要對請求參數做些判斷,看看是新增訊息或查詢,並要自行輸出XML,有的沒的…
改成DWR的話,就很簡單了,寫個簡單的Java物件…
1234567891011121314151617181920212223 package onlyfun.caterpillar; import java.util.LinkedList;import java.util.List; public class Chat { private static LinkedList<Message> messages = new LinkedList<Message>(); public List addMessage(String text) { if (text != null && text.trim().length() > 0) { messages.addFirst(new Message(text)); while (messages.size() > 10) { messages.removeLast(); } } return messages; } public List getMessages() { return messages; }}
接著…在dwr.xml中開放一下…
12345678910111213 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr> <allow> <create creator="new" javascript="Chat"> <param name="class" value="onlyfun.caterpillar.Chat"/> </create> <convert converter="bean" match="onlyfun.caterpillar.Message"/> </allow></dwr>
使用者取得訊息時,是直接傳回List物件,而List中裝的是Message物件,Message物件是自訂物件,conterver設定為 bean,表示DWR會自動將Message的getter名稱轉換為傳回客戶端的JavaScript物件中的屬性,例如Message中有 getText(),則在客戶端可以用message.text這樣的方式來存取。
接著是簡單的客戶端網頁…
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=BIG5"><title>Insert title here</title> <script src="dwr/interface/Chat.js" type="text/javascript"></script><script src="dwr/engine.js" type="text/javascript"></script><script src="dwr/util.js" type="text/javascript"></script> <script type="text/javascript">function sendMessage() { var text = DWRUtil.getValue("text"); DWRUtil.setValue("text", ""); Chat.addMessage(text, gotMessages);} function gotMessages(messages) { var chatlog = ""; for (var data in messages) { chatlog = "<div>" + messages[data].text + "</div>" + chatlog; } DWRUtil.setValue("chatlog", chatlog); setTimeout("queryMessage()", 2000);} function queryMessage() { Chat.getMessages(gotMessages);}</script> </head><body> <p> Your Message: <input id="text"/> <input type="button" value="Send" onclick="sendMessage()"/></p> <p>Messages:</p><div id="chatlog"></div> </body></html>
當List物件傳回時,它成為gotMessages(messages)中的messages物件,而messages物件中包括 Message物件轉換後對應的JavaScript物件,由於我們已經設定了Converter,所以可以用messages[data].text來 取得傳回的訊息…
簡單抓個畫面…
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/caterpillar_here/archive/2006/09/30/1311605.aspx