用AJAX写的聊天室(和淘宝上的阿里巴巴很像的工具条)

用AJAX写的聊天室(和淘宝下的阿里巴巴很像的工具条)
(例子见下面下载……)
1:页面
单击好友显示好友列表(这里是虚拟的),单击好友弹出对话框。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<html>
<head>
<title>聊天</title>
<link href="css.css" rel="stylesheet" type="text/css">
<script language="javascript" type="text/javascript">
   var _IsMousedown = 0;
   var _ClickLeft = 0;
   var _ClickTop = 0;
   function moveInit(divID,evt)
   {
    _IsMousedown = 1;
    if(getBrowserType() == "NSupport")
    {
     return;
    }
    var obj = getObjById(divID);
    if(getBrowserType() == "fox")
    {
     _ClickLeft = evt.pageX - parseInt(obj.style.left);
     _ClickTop = evt.pageY - parseInt(obj.style.top);
    }else{
     _ClickLeft = evt.x - parseInt(obj.style.left);
     _ClickTop = evt.y - parseInt(obj.style.top);
    }
   }
   function Move(divID,evt)
   {
    if(_IsMousedown == 0)
    {
     return;
    }
    var objDiv = getObjById(divID);
    if(getBrowserType() == "fox")
    {
     objDiv.style.left = evt.pageX - _ClickLeft;
     objDiv.style.top = evt.pageY - _ClickTop;
    }
    else{
     objDiv.style.left = evt.x - _ClickLeft;
     objDiv.style.top = evt.y - _ClickTop;
    }
    
   }
   function stopMove()
   {
    _IsMousedown = 0;
   }
   function getObjById(id)
   {
    return document.getElementById(id);
   }
   function getBrowserType()
   {
    var browser=navigator.appName
    var b_version=navigator.appVersion
    var version=parseFloat(b_version)
    //alert(browser);
    if ((browser=="Netscape"))
    {
     return "fox";
    }
    else if(browser=="Microsoft Internet Explorer")
    {
     if(version>=4)
     {
      return "ie4+";
     }
     else
     {
      return "ie4-";
     }
    }
    else
    {
     return "NSupport";
    }
   }
   
   	function showdiv1(){
			var d=document.getElementById('subpanel');
			d.style.display="block";

		}
		function hiddendiv1(name){
			var d=document.getElementById('subpanel');
			d.style.display="none";
			document.getElementById('movediv').style.display='block';
			document.getElementById('user').innerHTML=name
			document.getElementById("speaker").value=name;
		}
		function hiddendiv2(){
			document.getElementById('getmessage').onLoad="";
		}
</script>
</head>
<body onLoad="sendEmptyRequest();">
<div id="getmessage"></div>
<div id="footpanel">
		<ul id="mainpanel">
			<li id="chatpanel">
				<a href="#" class="chat" onClick="showdiv1()">在线好友(<em>6</em>)</a>
				<div class="subpanel" id="subpanel">
					<h3><span> &ndash; </span>在线好友</h3>
					<ul>
						<li><a href="#" onClick="hiddendiv1('张三')"><img src="img/user.png" />张三</a></li>
						<li><a href="#" onClick="hiddendiv1('李四')"><img src="img/user.png" />李四</a></li>
						<li><a href="#" onClick="hiddendiv1('王五')"><img src="img/user.png" />王五</a></li>
						<li><a href="#" onClick="hiddendiv1('赵六')"><img src="img/user.png" />赵六</a></li>
						<li><a href="#" onClick="hiddendiv1('abc')"><img src="img/user.png" />abc</a></li>
						<li><a href="#" onClick="hiddendiv1('123')"><img src="img/user.png" />123</a></li>
					</ul>
				</div>
			</li>
		</ul>
</div>

<div id="movediv" style="left:20px;top:20px;" onMouseDown="moveInit('movediv',event);" onMouseMove="Move('movediv',event)" onMouseUp="stopMove()" onMouseOut="stopMove()">
			      <table style="width:376px; background-color: #f0f5fb;border:none; ">
			          <tr>
			              <td width="40%">
			                  <span style="font-size:15px;">&nbsp;&nbsp;&nbsp;与<label id="user"></label>在线聊天中
			                  </span>
			              </td>
			              <td width="30%" style="text-align:right;">
			                  <span style="font-size:12px; font-style:Verdana;"><a href = "javascript:void(0)" onclick = "document.getElementById('movediv').style.display='none';">点这里关闭本窗口</a></span>
			              </td>
			          </tr>
			      </table>
			  <table id="$chat_table"  style="width:376px; background-color: #f0f5fb; ">
			      <tr>
			          <td style="height:200px; width:100%;">
			           <div align="center">
			              <textarea id="chatArea" name="chatArea" cols="40"
							rows="15" readonly="readonly"></textarea>
						</div>
			          </td>
			      </tr>
			      <tr>
			          <td style="height:20px;text-align:right; vertical-align:middle; width: 100%;-moz-user-select: text;">
			              <div align="center">
						      <input id="chatMsg" name="chatMsg" type="text"size="40"
						  	 onkeypress="enterHandler(event);"/>
						      <input type="button" name="button" value="提交"
						  	onclick="ajaxSubmit();"/>
						  	<input type=hidden id="speaker" value="">
						</div>
			          </td>
			      </tr>
			</table>

</div>

<script type="text/javascript">
 	var xmlHttpRequest = null;//声明一个变量来接受xmlHttpRequest对象
	function ajaxSubmit() {
		if (window.ActiveXObject) {//这是IE浏览器 
				xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");
		} else if (window.XMLHttpRequest) {//这是除IE外的其他浏览器 
				xmlHttpRequest = new XMLHttpRequest();
		}
		if (xmlHttpRequest != null) {
			var v1 = document.getElementById("speaker").value;
			var v2 = document.getElementById("chatMsg").value;
			//POST请求,ChatServlet是servlet,true的是异步,false就是同步   
			xmlHttpRequest.open("POST", "${pageContext.servletContext.contextPath }/ChatServlet", true);
			xmlHttpRequest.onreadystatechange = ajaxCallback;//关联好ajax的回调方法   
			document.getElementById("chatMsg").value="";
			xmlHttpRequest.setRequestHeader("Content-Type",
					"application/x-www-form-urlencoded")
			xmlHttpRequest.send("user=" + v1 + "&chatMsg=" + v2);
		}
	}
	 function sendEmptyRequest(){
		if (window.ActiveXObject) {
			xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");
		} else if (window.XMLHttpRequest) {
			xmlHttpRequest = new XMLHttpRequest();
		}
		if (xmlHttpRequest != null) {
			xmlHttpRequest.open("POST", "${pageContext.servletContext.contextPath }/ChatServlet", true);
			xmlHttpRequest.onreadystatechange = ajaxCallback;
			xmlHttpRequest.setRequestHeader("Content-Type",
					"application/x-www-form-urlencoded")
			xmlHttpRequest.send(null);
			//指定0.8s之后再次发送请求
			setTimeout("sendEmptyRequest()" , 800);
		} 	
	 }
	 // 处理返回信息函数
	function ajaxCallback() {
		//当XMLHttpRequest读取服务器响应完成       ReadyState共有5中状态(0,1,2,3,4)
		if (xmlHttpRequest.readyState == 4)
		{
			//服务器响应正确(当服务器响应正确时,返回值为200的状态码)
			if (xmlHttpRequest.status == 200)
			{
				//使用chatArea多行文本域显示服务器响应的文本
				document.getElementById("chatArea").value 
					= xmlHttpRequest.responseText;
			}
			//else
			//{
				//提示页面不正常
			//	window.alert("您所请求的页面有异常。");
			//}
	 	}
	}
	function enterHandler(event){
			//获取用户单击键盘的“键值”
			var keyCode = event.keyCode ? event.keyCode 
				: event.which ? event.which : event.charCode;
			//如果是回车键
			if (keyCode == 13){
				ajaxSubmit();
			}
	 }
</script>
</body>
</html>

2 css样式
#footpanel {
display: none;
position: fixed;
bottom: 0; left: 0;
z-index: 9999; /*制作出一个斜面,让工具栏看起来更有层次感*/
background: #e3e2e2;
border: 1px solid #c3c3c3;
border-bottom: none;
width: 370;
margin: 0 975px 0;
}
*html #footpanel { /*IE6 Hack 让工具栏定位底部*/
margin-top: -1px; /*修正IE6工具栏滚动条的1像素误差*/
position: absolute;
top:expression(eval(document.compatMode &&document.compatMode=='CSS1Compat') ?documentElement.scrollTop+(documentElement.clientHeight-this.clientHeight) : document.body.scrollTop +(document.body.clientHeight-this.clientHeight));
}
#footpanel ul {
padding: 0; margin: 0;
float: left;
width: 100%;
list-style: none;
border-top: 1px solid #fff; /*制作出一个斜面,让工具栏看起来更有层次感*/
font-size: 1em;
line-height:1em;
}
#footpanel ul li{
padding: 0; margin: 0;
float: left;
position: relative;
}
#footpanel ul li a{
padding: 5px;
float: left;
text-indent: -9999px;
height: 16px; width: 16px;
text-decoration: none;
color: #333;
position: relative;
}
html #footpanel ul li a:hover{ background-color: #fff; }
html #footpanel ul li a.active { /*当工具栏上的链接被点击,里面的菜单打开的状态*/
background-color: #fff;
height: 17px;
margin-top: -2px; /*在工具栏上向上提高2像素*/
border: 1px solid #555;
border-top: none;
z-index: 200; /*在工具栏上层显示*/
position: relative;
}
#footpanel a.chat{
background: url(balloon.gif) no-repeat 15px center;
width: 126px;
border-left: 1px solid #bbb;
padding-left: 40px;
text-indent: 0; /*将上面的文字位移去掉*/
}
#footpanel li#chatpanel { float: right; } /*让好友列表居右显示*/
#footpanel a small {
text-align: center;
width: 70px;
background: url(pop_arrow.gif) no-repeat center bottom;
padding: 5px 5px 11px;
display: none; /*默认状态为隐藏*/
color: #fff;
font-size: 1em;
text-indent: 0;
}
#footpanel a:hover small{
display: block; /*悬浮时显示*/
position: absolute;
top: -35px; /*在工具栏上方35像素位置显示--*/
left: 50%;
margin-left: -40px; /*居中*/
z-index: 9999;
}
#footpanel ul li div a {
text-indent: 0;/*关键就是它*/
width: auto;
height: auto;
padding: 0;
float: none;
color: #00629a;
position: static;
}
#footpanel ul li div a:hover { text-decoration: underline; }
/*999*/
#footpanel .subpanel {
position: absolute;
left: 0; bottom: 27px;
display: none; /*默认应为隐藏,但现在为了演示,将其设定为block,制作成功后应该为none*/
width: 125px;
border: 1px solid #555;
background: #fff;
overflow: hidden;
padding-bottom: 2px;
}
#footpanel h3 {
background: #526ea6;
padding: 5px 10px;
color: #fff;
font-size: 1.1em;
cursor: pointer;
}
#footpanel h3 span {
font-size: 1.5em;
float: right;
line-height: 0.6em;
font-weight: normal;
}
#footpanel .subpanel ul{
padding: 0; margin: 0;
background: #fff;
width: 100%;
overflow: auto;
}
#footpanel .subpanel li {
float: none; /*取消上面定义的居左浮动-*/
display: block;
padding: 0; margin: 0;
overflow: hidden;
clear: both;
background: #fff;
position: static; /*取消上面定义的相对定位*/
font-size: 1em;
}
#chatpanel .subpanel li a img {
float: left;/*让图片居左显示*/
margin: 0 5px;
}
#chatpanel .subpanel li a{
padding: 3px 0; margin: 0;
line-height: 22px;
height: 22px;
background: #fff;
display: block;/*让链接呈块状显示,可点击区域变大*/
}
#chatpanel .subpanel li a:hover {
background: #3b5998;
color: #fff;
text-decoration: none;
}
#movediv{
	    display: none;
	    width:100px;
		height:273px;position:absolute;border:1px solid #000;background:#EAEAEA;
	    cursor:pointer;
	    text-align:center;
	    left:100px;
	    top:10px;
  	 }

3.请求发送到后台ChatServlet,ChatServlet调用ChatService
ChatService
package com.happysys.im;

import java.util.LinkedList;

public class ChatService {
	//使用单例模式来设计ChatService
	private static ChatService cs;
	//使用LinkedList对象保存聊天信息
	private LinkedList<String> chatMsg;
	//构造器私有
	private ChatService()
	{
	}
	//通过静态方法返回唯一的ChatService对象
	public static ChatService instance()
	{
		if (cs == null)
		{
			cs = new ChatService();
		}
		return cs;
	}
	//获取系统中所有聊天信息
	public String getMsg()
	{
		//如果chatMsg对象为null,表明不曾开始聊天
		if (chatMsg == null)
		{
			chatMsg = new LinkedList<String>();
			return "";
		}
		StringBuilder result = new StringBuilder("");
		//将chatMsg中所有聊天信息拼接起来。
		for (String tmp : chatMsg)
		{
			result.append(tmp + "\n");
		}
		return result.toString();
	}
	//用户发言,添加聊天信息
	public void addMsg(String user , String msg)
	{
		///如果chatMsg对象为null,初始化chatMsg对象
		if (chatMsg == null)
		{
			chatMsg = new LinkedList<String>();
		}
		//最多保存40条聊天信息,当超过40条之后,将前面聊天信息删除
		if (chatMsg.size() > 40)
		{
			chatMsg.removeFirst();
		}
		//添加新的聊天信息
		chatMsg.add("对"+user + "说:" + msg);
	}
}


ChatServlet
package com.happysys.im;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ChatServlet extends HttpServlet {


	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doPost(request,response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		//设置使用UTF-8字符集来解析请求参数
		//XMLHttpRequest所发送的POST请求默认采用UTF-8字符集
        request.setCharacterEncoding("UTF-8");
		String msg = request.getParameter("chatMsg");
		System.out.println(msg);
		
		if ( msg != null &&  !msg.equals(""))
		{
			//取得当前用户
			//String user = (String)request.getSession(true).getAttribute("user");
			String user=request.getParameter("user");
			//调用ChatService的addMsg来添加聊天消息
			ChatService.instance().addMsg(user , msg);
			System.out.println(user);
		}
		//设置响应内容的类型
		response.setContentType("text/html;charset=utf-8");
		//获取页面输出流
		PrintWriter out = response.getWriter();
		//直接生成响应
		out.println(ChatService.instance().getMsg());
	}
}