來寫個AJAX版的聊天室吧!先看看直接使用AJAX要如何做到,首先需要一個簡單的聊天室Servlet…
onlyfun.caterpillar; java.io.IOException; java.io.PrintWriter; java.util.LinkedList; java.util.List; javax.servlet.ServletException; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; ChatRoomServlet javax.servlet.http.HttpServlet javax.servlet.Servlet LinkedList<Message> messages = LinkedList<Message>(); ChatRoomServlet() (); List<Message> addMessage(String text) (text != && text.trim().length() > 0) messages.addFirst( Message(text)); (messages.size() > 10) messages.removeLast(); messages; List<Message> getMessages() messages; doPost(HttpServletRequest request, HttpServletResponse response) ServletException, IOException List<Message> list = ; (.equals(request.getParameter())) list = addMessage(request.getParameter()); (.equals(request.getParameter())) list = getMessages(); PrintWriter out = response.getWriter(); response.setContentType(); response.setHeader(, ); out.println(); ( i = 0; i < list.size(); i++) String msg = list.get(i).getText(); out.println( + msg + ); out.println();
Message物件如下…
onlyfun.caterpillar; Message id = System.currentTimeMillis(); String text; Message(String newtext) text = newtext; (text.length() > 256) text = text.substring(0, 256); text = text.replace(, ); text = text.replace(, ); getId() id; String getText() text;
Servlet接受訊息新增與查詢,判斷的方式是檢查請求參數task是send或query。
Servlet會以XML傳回目前List當中的訊息,客戶端可以查詢或插入新訊息時,取得目前List中的訊息,接著在web.xml中設定一下…
<?xml version= encoding=?> <web-app id= version= xmlns= xmlns:xsi= xsi:schemaLocation=> <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回應取得時,將訊息以一列一列的表格方式顯示出來,另外還設定了週期性的輪詢,即使不輸入新訊息,也可以週期性的取得新的聊天訊息…
<!DOCTYPE HTML PUBLIC > <html> <head> <meta http-equiv= content=> <title>Chat Room</title> <script type=> var xmlHttp; function createXMLHttpRequest() (window.ActiveXObject) xmlHttp = ActiveXObject(); (window.XMLHttpRequest) xmlHttp = XMLHttpRequest(); function sendMessage() var msg = document.getElementById().value; (msg == ) refreshMessage(); ; var param = + msg; ajaxRequest(param); document.getElementById().value = ; function queryMessage() var param = ; ajaxRequest(param); function ajaxRequest(param) var url = + Date().getTime(); createXMLHttpRequest(); xmlHttp.onreadystatechange = refreshMessage; xmlHttp.open(, url, ); xmlHttp.setRequestHeader(, ); xmlHttp.send(param); function refreshMessage() (xmlHttp.readyState == 4) (xmlHttp.status == 200) var messages = xmlHttp.responseXML.getElementsByTagName(); var table_body = document.getElementById(); var length = table_body.childNodes.length; (var i = 0; i < length; i++) table_body.removeChild(table_body.childNodes[0]); var length = messages.length; (var i = length - 1; i >= 0 ; i--) var message = messages[i].firstChild.data; var row = createRow(message); table_body.appendChild(row); setTimeout(, 2000); function createRow(message) var row = document.createElement(); var cell = document.createElement(); var cell_data = document.createTextNode(message); cell.appendChild(cell_data); row.appendChild(cell); row; </script> </head> <body> <p> Your Message: <input id=/> <input type= value= onclick=/> </p> <p>Messages:</p> <table align=> <tbody id=></tbody> </table> </body> </html>
簡單抓個畫面…
直接用AJAX,後端用JSP/Servlet,您要對請求參數做些判斷,看看是新增訊息或查詢,並要自行輸出XML,有的沒的… 改成DWR的話,就很簡單了,寫個簡單的Java物件…
onlyfun.caterpillar; java.util.LinkedList; java.util.List; Chat LinkedList<Message> messages = LinkedList<Message>(); List addMessage(String text) (text != && text.trim().length() > 0) messages.addFirst( Message(text)); (messages.size() > 10) messages.removeLast(); messages; List getMessages() messages;
接著…在dwr.xml中開放一下…
<?xml version= encoding=?> <!DOCTYPE dwr PUBLIC > <dwr> <allow> <create creator= javascript=> <param name= value=/> </create> <convert converter= match=/> </allow> </dwr>
使用者取得訊息時,是直接傳回List物件,而List中裝的是Message物件,Message物件是自訂物件,conterver設定為 bean,表示DWR會自動將Message的getter名稱轉換為傳回客戶端的JavaScript物件中的屬性,例如Message中有 getText(),則在客戶端可以用message.text這樣的方式來存取。
接著是簡單的客戶端網頁…
<!DOCTYPE HTML PUBLIC > <html> <head> <meta http-equiv= content=> <title>Insert title here</title> <script src= type=></script> <script src= type=></script> <script src= type=></script> <script type=> function sendMessage() var text = DWRUtil.getValue(); DWRUtil.setValue(, ); Chat.addMessage(text, gotMessages); function gotMessages(messages) var chatlog = ; (var data in messages) chatlog = + messages[data].text + + chatlog; DWRUtil.setValue(, chatlog); setTimeout(, 2000); function queryMessage() Chat.getMessages(gotMessages); </script> </head> <body> <p> Your Message: <input id=/> <input type= value= onclick=/> </p> <p>Messages:</p> <div id=></div> </body> </html>
當List物件傳回時,它成為gotMessages(messages)中的messages物件,而messages物件中包括 Message物件轉換後對應的JavaScript物件,由於我們已經設定了Converter,所以可以用messages[data].text來 取得傳回的訊息…
簡單抓個畫面…