这是个web聊天程序,很不错的,采用serverpush技术。
1.servlet(SpeakHouse.java 聊天室控制):
/**
* 聊天室程序
*/
public class SpeakHouse
extends HttpServlet {
/* 保存用户列表 */
static public ArrayList vecUserList = null;
/* 保存用户发言内容 */
static public ArrayList vecContentList = null;
/**
* 初始化类
*/
public SpeakHouse() {
if (vecUserList == null) {
vecUserList = new ArrayList();
vecUserList.add("所有人");
}
if (vecContentList == null) {
vecContentList = new ArrayList();
}
}
/**
* 初始化
*/
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
/**
* 清除
*/
public void destroy() {
super.destroy();
}
/**
* 控制程序
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void service(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
/* SystemUserInfo user=new SystemUserInfo(); //me
user.setUserName("test"+i++); //
request.getSession().setAttribute("session_UserInfo", user); //
*/
try {
PrintWriter out = new PrintWriter(response.getOutputStream());
setDefault(request, response);
/*请求的是哪个页面*/
//String strPage = ParamUtil.getParameter(request,"page");
String strPage=request.getParameter("page");
/* 显示主页面 */
if ("".equals(strPage) || strPage == null) {
showMainframe(out);
}
/* 显示发言内容 */
if ("ContentList".equals(strPage)) {
showDefault(out);
// showContentListframe(out,((SystemUserInfo)ContextUtil.getSessionObject(request,"session_UserInfo")).getUserName(),request,DateUtil.getNowTime());
showContentListframe(out,((SystemUserInfo)request.getSession().getAttribute("session_UserInfo")).getUserName(),request,DateUtil.getNowTime());
}
/* 显示用户列表 */
if ("UserList".equals(strPage)) {
showDefault(out);
showUserListframe(out);
}
if ("SpeakList".equals(strPage)) {
/* 保存发言内容 */
//String content = filter(ParamUtil.getParameter(request,"content"));
String content = filter(request.getParameter("content"));
//String isPrivate=ParamUtil.getParameter(request,"isPrivate");
String isPrivate=request.getParameter("isPrivate");
//String name=((SystemUserInfo)ContextUtil.getSessionObject(request,"session_UserInfo")).getUserName();
String name=((SystemUserInfo)request.getSession().getAttribute("session_UserInfo")).getUserName();
//聊的对象
//String toUser=filter(ParamUtil.getParameter(request,"toUser"));
String toUser=filter(request.getParameter("toUser"));
//是否退出聊天室
//String type=ParamUtil.getParameter(request,"type");
String type=request.getParameter("type");
if("exit".equals(type)){
UserSpeakContent closeSpeak=new UserSpeakContent();
if(vecUserList.indexOf(name)>0){
vecUserList.remove(name);
closeSpeak.setSpeakTime(DateUtil.getNowTime());
closeSpeak.setSpeakUser(name);
closeSpeak.setToSpeakUser("");
closeSpeak.setSpeakContent(name+"退出聊天室");
closeSpeak.setLogout(true);
closeSpeak.setSpeakType(1);
vecContentList.add(closeSpeak);
}
showDefault(out);
showSpeakListframe(out, name,closeSpeak.getToSpeakUser(),closeSpeak.isPrivate());
}else{
if("".equals(toUser)){
toUser="";
}
UserSpeakContent userSpeakContent=new UserSpeakContent();
/*表示刚刚进入聊天室*/
//if(!"".equals(name) && "".equals(content)){
if(name!=null && content==null){
userSpeakContent.setSpeakTime(DateUtil.getNowTime());
userSpeakContent.setSpeakUser("***系统信息***");
userSpeakContent.setToSpeakUser("所有人");
userSpeakContent.setSpeakContent(name+"刚刚进入聊天室");
userSpeakContent.setSpeakType(1);
}else{
if("私聊".equals(isPrivate)){
userSpeakContent.setPrivate(true);
}
userSpeakContent.setSpeakContent(content);
userSpeakContent.setSpeakTime(DateUtil.getNowTime());
userSpeakContent.setSpeakUser(name);
userSpeakContent.setToSpeakUser(toUser);
}
/*刚刚进入聊天室*/
//if(!"".equals(name) && "".equals(content)){
if(name!=null&&content==null){
if(vecUserList.indexOf(name)<0){ //在线用户中没有这个人
vecUserList.add(name);
}
}
if(vecUserList.indexOf(userSpeakContent.getSpeakUser())>0 && vecUserList.indexOf(userSpeakContent.getToSpeakUser())>0){ //说话人在线,聊天对象也在线
vecContentList.add(userSpeakContent);
}else if(vecUserList.indexOf(userSpeakContent.getSpeakUser())>0 && userSpeakContent.getToSpeakUser().equals("所有人")){ //说话人在线,聊天对象是所有人
vecContentList.add(userSpeakContent);
}else if(userSpeakContent.getSpeakType()==1){ //是系统信息
vecContentList.add(userSpeakContent);
}else if(vecUserList.indexOf(userSpeakContent.getSpeakUser())>0 && vecUserList.indexOf(userSpeakContent.getToSpeakUser())<0){ //说话人在线,聊天对象不在线
out.println("<script>alert('"+userSpeakContent.getToSpeakUser()+"已经下线!');</script>");
out.flush();
}
showDefault(out);
showSpeakListframe(out, name,userSpeakContent.getToSpeakUser(),userSpeakContent.isPrivate());
}
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 设页面初始参数
* @param request
* @param response
* @throws java.lang.Exception
*/
private void setDefault(HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.setBufferSize(1024 * 64);
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.setDateHeader("Expires", -1);
response.setContentType("text/html; charset=gbk");
request.setCharacterEncoding("GBK");
}
/**
* 输出页面头
* @param out
*/
private void showDefault(PrintWriter out) {
String[] strOut = new String[] {
"<html>",
"<head>",
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=gbk\">",
"<title></title>",
"<!--",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"-->",
"<style type=\"text/css\">",
"<!--",
"body {overflow :auto; font-size: 9pt; background-color: #e0e0e0;}",
"-->",
"</style>",
"</head>",
"<script>window.status='聊天室';</script>",
"<body>"
};
for (int i = 0; i < strOut.length; i++) {
out.println(strOut[i]);
}
out.flush();
}
/**
* 显示主页面
* @param out
* @throws java.lang.Exception
*/
private void showMainframe(PrintWriter out) throws Exception {
String[] strOut = new String[] {
"<html>",
"<head>",
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=gbk\">",
"<title>聊天室</title>",
"</head>",
"<frameset rows=\"*\" cols=\"100,*\" frameborder=\"YES\" border=\"1\" framespacing=\"0\">",
"<frame src=\"speakHouse?page=UserList\" name=\"UserListframe\" scrolling=\"NO\" noresize>",
"<frameset rows=\"*,70\" cols=\"*\" framespacing=\"0\" frameborder=\"YES\" border=\"1\">",
"<frame src=\"speakHouse?page=ContentList\" name=\"ContentListframe\">",
"<frame src=\"speakHouse?page=SpeakList\" name=\"SpeakListframe\" scrolling=\"NO\" noresize>",
"</frameset>",
"</frameset>",
"<noframes><body>",
"</body></noframes>",
"</html>",
};
for (int i = 0; i < strOut.length; i++) {
out.println(strOut[i]);
}
out.close();
}
/**
* 显示用户发言内容
* @param out
* @throws java.lang.Exception
*/
private void showContentListframe(PrintWriter out,String userName,HttpServletRequest request,Date logTime) {
int inListCount = 0;
int inUserList = 0;
UserSpeakContent userSpeakContent = null;
boolean isLogined=false;
boolean canLogout=false;
boolean isSpeak=false;
while (true) {
for(int i=vecContentList.size()-1;i>=0;i--){
userSpeakContent = (UserSpeakContent) vecContentList.get(i);
if(userSpeakContent.getSpeakUser().equals(userName)){
isSpeak=true;
//如果用户在线上,并且大余30分钟不发言,退出
if(vecUserList.indexOf(userName)>0 &&userSpeakContent.getSpeakType()==0){
if(DateUtil.getTwoTimeSub(DateUtil.getNowTime(),userSpeakContent.getSpeakTime())>=30){
//在线列表中删除userName这个人
vecUserList.remove(userName);
canLogout=true;
break;
}else{
break;
}
}else{
break;
}
}
}
if(isSpeak==false){
if(vecUserList.indexOf(userName)>0){
if(DateUtil.getTwoTimeSub(DateUtil.getNowTime(),logTime)>=30){
vecUserList.remove(userName);
canLogout=true;
}
}
isSpeak=true;
}
if (inListCount < vecContentList.size()) {
while (inListCount < vecContentList.size()) {
inListCount++;
userSpeakContent = (UserSpeakContent) vecContentList.get(inListCount - 1);
userSpeakContent= filterSelfMessage(userSpeakContent,userName);
if(userSpeakContent!=null){
//显示在登录前5分钟的信息
if(DateUtil.getTwoTimeSub(userSpeakContent.getSpeakTime(),logTime)>=-5){
if(userSpeakContent.getSpeakType()==1){ //系统信息
showSystemContent(out,userSpeakContent); //显示信息信息
}else{
if(userSpeakContent.getToSpeakUser().equals("所有人") && userSpeakContent.getSpeakUser().equals(userName)){
showSelfToAllContent(out,userSpeakContent);
}else if(userSpeakContent.getToSpeakUser().equals("所有人") && !userSpeakContent.getSpeakUser().equals(userName)){
showOtherToAllContent(out,userSpeakContent);
}else if(userSpeakContent.getSpeakUser().equals(userName) && userSpeakContent.getToSpeakUser().equals(userName)){//你对自己说的
if(userSpeakContent.isPrivate()){
showSelfToSelfContentPrivate(out,userSpeakContent); //自己对自己说悄悄话
}else{
showSelfToSelfContent(out,userSpeakContent); //自己对自己说
}
}else if(userSpeakContent.getSpeakUser().equals(userName) && !userSpeakContent.getToSpeakUser().equals(userName)){ //你对别的说的
if(userSpeakContent.isPrivate()){
showSelfToOtherContentPrivate(out,userSpeakContent); //自己对别人说的悄悄话
}else{
showSelfToOtherContent(out,userSpeakContent); //自己对别人说的话
}
}else if(!userSpeakContent.getSpeakUser().equals(userName) && !userSpeakContent.getToSpeakUser().equals(userName)){ //不是你说的,也不是对你说的
if(userSpeakContent.isPrivate()){
showOtherToOtherContentPrivate(out,userSpeakContent); //别人对别人说的悄悄话
}else{
showOtherToOtherContent(out,userSpeakContent); //别人对别人说的话
}
}else if(!userSpeakContent.getSpeakUser().equals(userName) && userSpeakContent.getToSpeakUser().equals(userName)){ //别人对你说的
if(userSpeakContent.isPrivate()){
showOtherToSelfContentPrivate(out,userSpeakContent); //别人对自己说的悄悄话
}else{
showOtherToSelfContent(out,userSpeakContent); //别人对自己说的话
}
}
}
}
}
}
out.println("<script>window.scroll(0,10000000);</script>");
out.flush();
}
//alert(top.UserListframe) 在线用户没有显示
// out.print("<SCRIPT>try{;top.fraRightFrame.main.UserListframe.document.all.LIST.innerHTML=\"");
out.print("<SCRIPT>try{;top.UserListframe.document.all.LIST.innerHTML=\"");
for (int i = 0; i < vecUserList.size(); i++) {
// out.print("<a href=# οnclick=top.fraRightFrame.main.SpeakListframe.document.all.toUser.value='"+vecUserList.get(i).toString()+"'>" + vecUserList.get(i).toString()+"</a><br>");
out.print("<a href=# οnclick=top.SpeakListframe.document.all.toUser.value='"+vecUserList.get(i).toString()+"'>" + vecUserList.get(i).toString()+"</a><br>");
}
//out.print("list.size="+vecUserList.size());//me 在线用户显示不出来
out.print("\"}catch(e){;}</SCRIPT>\n");
out.flush();
inUserList = vecUserList.size();
try{
Thread.sleep(500);
}catch(Exception e){
System.out.println("线程出错"+e);
}
if(canLogout){
UserSpeakContent closeSpeak=new UserSpeakContent();
closeSpeak.setSpeakTime(DateUtil.getNowTime());
closeSpeak.setSpeakUser(userName);
closeSpeak.setToSpeakUser("");
closeSpeak.setSpeakContent(userName+"退出聊天室");
closeSpeak.setLogout(true);
closeSpeak.setSpeakType(1);
vecContentList.add(closeSpeak);
out.println("<LI><B>***系统信息*** 你由于30分钟没发言,已经自动退出聊天室!</LI></B>");
out.flush();
canLogout=false;
break;
}
}
}
/**
* 显示用户列表
* @param out
* @throws java.lang.Exception
*/
private void showUserListframe(PrintWriter out) throws Exception {
out.println(
"<CENTER>在线用户</CENTER><HR><FONT ID=\"LIST\"></FONT></BODY></HTML>");
out.close();
}
/**
* 显示用户发言录入框
* @param out
* @param name
* @throws java.lang.Exception
*/
private void showSpeakListframe(PrintWriter out, String name,String toUser,boolean isPrivate) throws
Exception {
String checkStr="";
String[] strOut = new String[] {
"<form method=\"post\" action=\"\" οnsubmit=\"if(document.all.content.value==''){alert('请输入你的发言');document.all.content.focus();return false;}\">",
"<input type=\"text\" name=\"name\" size=10 readOnly=true style=\"background-color: #66FFFF\">",
"对<input type=\"text\" name=\"toUser\" size=10 readOnly=true style=\"background-color: #66FFFF\">",
"<input type=\"checkbox\" name=\"isPrivate\" value=\"私聊\">私聊 ",
"说<input type=\"text\" name=\"content\" size=50>",
"<input type=submit value=' 发 表 '>",
" <a href=\"?page=SpeakList&type=exit\">退出</a>",
"</form>",
"<script>",
"document.all.content.focus();",
"</script>"
};
for (int i = 0; i < strOut.length; i++) {
out.println(strOut[i]);
}
if (!"".equals(name) && name != null) {
checkStr="<script>document.all.name.value='" + name +"';document.all.toUser.value='"+toUser+"';";
if(isPrivate){
checkStr=checkStr+"document.all.isPrivate.checked=true;";
}
checkStr=checkStr+"</script>";
out.println(checkStr);
}
out.close();
}
/**
* 改变为HTML字符
* @param value
* @return
*/
public static String filter(String value) {
if (value == null) {
return null;
}
char content[] = new char[value.length()];
value.getChars(0, value.length(), content, 0);
StringBuffer result = new StringBuffer(content.length + 50);
for (int i = 0; i < content.length; i++) {
switch (content[i]) {
case 60: // '<'
result.append("<");
break;
case 62: // '>'
result.append(">");
break;
case 38: // '&'
result.append("&");
break;
case 34: // '"'
result.append(""");
break;
case 39: // '\''
result.append("'");
break;
case 32: // ' '
result.append(" ");
break;
default:
result.append(content[i]);
break;
}
}
return result.toString();
}
public UserSpeakContent filterSelfMessage(UserSpeakContent content,String user){
//发给自己的私聊内容
if(content.isPrivate() && content.getToSpeakUser().equals(user)){
return content;
}
//公聊内容
if(content.isPrivate()==false){
return content;
}
//自己发的内容
if(content.getSpeakUser().equals(user)){
return content;
}
//发给所有人的内容
if(content.getToSpeakUser().equals("所有人")){
return content;
}
return null;
}
//显示系统信息
private void showSystemContent(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>***系统信息***</B> " + userSpeakContent.getSpeakContent() + "</LI>");
}
//显示用户自己对自己说
private void showSelfToSelfContent(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>你自言自语道: " + userSpeakContent.getSpeakContent() + "</B></LI>");
}
//显示用户自己对自己说的悄悄话
private void showSelfToSelfContentPrivate(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>你悄悄地自言自语道: " + userSpeakContent.getSpeakContent() + "</B></LI>");
}
//显示自己对别人说的悄悄话
private void showSelfToOtherContentPrivate(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>你</B> 对 " + userSpeakContent.getToSpeakUser() + " 悄悄地说: " + userSpeakContent.getSpeakContent() + "</LI>");
}
//显示自己对别人说的话
private void showSelfToOtherContent(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>你</B> 对 " + userSpeakContent.getToSpeakUser() + "说: " + userSpeakContent.getSpeakContent() + "</LI>");
}
//显示别人对别人说的悄悄话
private void showOtherToOtherContentPrivate(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>" + userSpeakContent.getSpeakUser() +
"</B> 对 " + userSpeakContent.getToSpeakUser() + " 悄悄地说: " + userSpeakContent.getSpeakContent() +
"</LI>");
}
//显示别人对别人说的话
private void showOtherToOtherContent(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>" + userSpeakContent.getSpeakUser() +
"</B> 对 " + userSpeakContent.getToSpeakUser() + "说: " + userSpeakContent.getSpeakContent() +
"</LI>");
}
//显示别人对自己说的悄悄话
private void showOtherToSelfContentPrivate(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>" + userSpeakContent.getSpeakUser() +
"</B> 对你悄悄地说: " + userSpeakContent.getSpeakContent() +
"</LI>");
}
//显示别人对自己说的话
private void showOtherToSelfContent(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>" + userSpeakContent.getSpeakUser() +
"</B> 对你说: " + userSpeakContent.getSpeakContent() +
"</LI>");
}
//显示你对所有人说的话
private void showSelfToAllContent(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>你</B> 对 所有人说: " + userSpeakContent.getSpeakContent() + "</LI>");
}
//显示别人对所有人说的话
private void showOtherToAllContent(PrintWriter out,UserSpeakContent userSpeakContent) {
out.println("<LI><B>"+userSpeakContent.getSpeakUser()+"</B> 对 所有人说: " + userSpeakContent.getSpeakContent() + "</LI>");
}
}
2.servlet:(LoginServlet.java: 登陆入口)
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String name=req.getParameter("name");
SystemUserInfo user=new SystemUserInfo();
user.setUserName(name);
req.getSession().setAttribute("session_UserInfo", user); //聊天室需要把用户名保存在session中
req.getRequestDispatcher("/speakHouse").forward(req, resp);
}
}
3.SystemUserInfo.java:
public class SystemUserInfo {
private String userName;
}
4.DateUtil.java
public class DateUtil {
public static Date getNowTime() {
Date nowTime=new Date();
return nowTime;
}
public static long getTwoTimeSub(Date end,Date start){
long minutes=(end.getTime()-start.getTime())/(1000*60);
return minutes;
}
}