入門與應用(三)

zengbo0710發表於2007-05-15
來寫個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來 取得傳回的訊息…

簡單抓個畫面…

 

相關文章