登录页面:Chatindex.jsp
<%@page contentType="text/html" pageEncoding="UTF-8" %> <html> <title> 寝室圈 </title> <link href="css/Chatstyle.css" rel="stylesheet"> <script language="javascript"> function check(){ if(form1.username.value==""){ alert("请输入用户名!");form1.username.focus();return false; }else if(form1.username.value=="\‘"){ alert("请不要输入非法字符!");form1.username.focus();return false; } } </script> <body> <br> <form name="form1" method="post" action="Messages?action=loginRoom" onSubmit="return check()"> <table width="371" height="230" border="0" align="center" cellpadding="0" cellspacing="0" background="Chatimages/login.jpg"> <tr> <td height="158" colspan="3" class="word_dark"> </td> </tr> <tr> <td width="53" align="center" valign="top" class="word_dark"> </td> <td width="216" align="center" valign="top" class="word_dark">用户名: <input type="text" name="username" class="login"></td> <td width="94" valign="top" class="word_dark"><input name="Submit" type="submit" class="btn_bg" value="进 入"></td> </tr> </table> </form> </body> </html>
聊天页面:Chatmain.jsp
<%@page contentType="text/html" pageEncoding="UTF-8" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ include file="Chatsafe.jsp"%> <html> <head> <title>寝室圈</title> <link href="css/Chatstyle.css" rel="stylesheet"> <script language="javascript" src="js/AjaxRequest.js"></script> <script language="javascript"> window.setInterval("showContent();",1000);//设置每过一秒钟刷新一次内容 window.setInterval("showOnline();",10000);//每过10秒钟刷新一次在线人数 var sysBBS="<span style=‘font-size:14px; line-height:30px;‘>欢迎进入寝室圈,请遵守寝室圈规则,不要使用不文明用语。</span><br><span style=‘line-height:22px;‘>"; //此处需要加?nocache="+new Date().getTime(),否则将出现在线人员列表不更新的情况 function showOnline(){ var loader=new net.AjaxRequest("Chatonline.jsp?nocache="+new Date().getTime(),deal_online,onerror,"GET"); } //Ajax每次请求的时候,返回响应的时间,对应的文本内容,然后关闭窗口 function showContent(){ var loader1=new net.AjaxRequest("Messages?action=getMessages&nocache="+new Date().getTime(),deal_content,onerror,"GET"); } function onerror(){ alert("很抱歉,服务器出现错误,当前窗口将关闭!"); window.opener=null; window.close(); } function deal_online(){ online.innerHTML=this.req.responseText; } function deal_content(){ var returnValue=this.req.responseText; //获取Ajax处理页的返回值 var h=returnValue.replace(/\s/g,""); //去除字符串中的Unicode空白符 if(h=="error"){ //alert("您的账户已经过期,请重新登录!"); Exit(); }else{ content.innerHTML=sysBBS+returnValue+"</span>"; document.getElementById(‘content‘).scrollTop = document.getElementById(‘content‘).scrollHeight*2; //当聊天信息超过一屏时,设置最先发送的聊天信息不显示 } } window.onload=function(){ showContent(); //当页面载入后显示聊天内容 showOnline(); //当页面载入后显示在线人员列表 } window.onbeforeunload=function(){ //当用户单击浏览器中的关闭按钮时执行退出操作 if(event.clientY<0 && event.clientX>document.body.scrollWidth){ Exit(); //执行退出操作 } } </script> <script language="javascript"> <!-- function send(){ //验证聊天信息并发送 if(form1.to.value==""){ alert("请选择聊天对象!");return false; } if(form1.content1.value==""){ alert("发送信息不可以为空!");form1.content1.focus();return false; } var param="from="+form1.from.value+"&face="+form1.face.value+"&color="+form1.color.value+"&to="+form1.to.value+"&content="+ form1.content1.value; var loader=new net.AjaxRequest("Messages?action=sendMessage",deal_send,onerror,"POST",param); } function deal_send(){ content.innerHTML=sysBBS+this.req.responseText+"</span>"; } function Exit(){ window.location.href="Chatleave.jsp"; alert("欢迎您下次光临!"); } --> </script> <script language="javascript"> function set(selectPerson){ //自动添加聊天对象 if(selectPerson!="${username}"){ form1.to.value=selectPerson; }else{ alert("请重新选择聊天对象!"); } } </script> <script type="text/javascript"> function checkScrollScreen(){ if(!form1.scrollScreen.checked){ document.getElementById("content").style.overflow=‘scroll‘; }else{ document.getElementById("content").style.overflow=‘hidden‘; //当聊天信息超过一屏时,设置最先发送的聊天信息不显示 document.getElementById(‘content‘).scrollTop = document.getElementById(‘content‘).scrollHeight*2; } setTimeout(‘checkScrollScreen()‘,500); } </script> </head> <body> <table width="778" height="150" border="0" align="center" cellpadding="0" cellspacing="0" background="Chatimages/top.jpg"> <tr> <td> </td> </tr> </table> <table width="778" height="276" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td width="165" valign="top" bgcolor="#f6fded" id="online" style="padding:5px">在线人员列表</td> <td width="613" height="200px" valign="top" background="Chatimages/main_bj.jpg" bgcolor="#FFFFFF" style="padding:5px; "> <div style="height:290px; overflow:hidden" id="content">聊天内容</div> </td> </tr> </table> <table width="778" height="95" border="0" align="center" cellpadding="0" cellspacing="0" bordercolor="#D6D3CE" background="Chatimages/bottom.jpg"> <form action="" name="form1" method="post" > <tr> <td height="30" align="left"> </td> <td height="37" align="left"><input name="from" type="hidden" value="${username}">[${username} ]对 <input name="to" type="text" value="" size="35" readonly="readonly"> 表情 <select name="face" class="wenbenkuang"> <option value="无表情的">无表情的</option> <option value="微笑着" selected>微笑着</option> <option value="笑呵呵地">笑呵呵地</option> <option value="热情的">热情的</option> <option value="温柔的">温柔的</option> <option value="红着脸">红着脸</option> <option value="幸福的">幸福的</option> <option value="嘟着嘴">嘟着嘴</option> <option value="热泪盈眶的">热泪盈眶的</option> <option value="依依不舍的">依依不舍的</option> <option value="得意的">得意的</option> <option value="神秘兮兮的">神秘兮兮的</option> <option value="恶狠狠的">恶狠狠的</option> <option value="大声的">大声的</option> <option value="生气的">生气的</option> <option value="幸灾乐祸的">幸灾乐祸的</option> <option value="同情的">同情的</option> <option value="遗憾的">遗憾的</option> <option value="正义凛然的">正义凛然的</option> <option value="严肃的">严肃的</option> <option value="慢条斯理的">慢条斯理的</option> <option value="无精打采的">无精打采的</option> </select> 说:</td> <td width="189" align="left"> 字体颜色: <select name="color" size="1" class="wenbenkuang" id="select"> <option selected>默认颜色</option> <option style="color:#FF0000" value="FF0000">红色热情</option> <option style="color:#0000FF" value="0000ff">蓝色开朗</option> <option style="color:#ff00ff" value="ff00ff">桃色浪漫</option> <option style="color:#009900" value="009900">绿色青春</option> <option style="color:#009999" value="009999">青色清爽</option> <option style="color:#990099" value="990099">紫色拘谨</option> <option style="color:#990000" value="990000">暗夜兴奋</option> <option style="color:#000099" value="000099">深蓝忧郁</option> <option style="color:#999900" value="999900">卡其制服</option> <option style="color:#ff9900" value="ff9900">镏金岁月</option> <option style="color:#0099ff" value="0099ff">湖波荡漾</option> <option style="color:#9900ff" value="9900ff">发亮蓝紫</option> <option style="color:#ff0099" value="ff0099">爱的暗示</option> <option style="color:#006600" value="006600">墨绿深沉</option> <option style="color:#999999" value="999999">烟雨蒙蒙</option> </select></td> <td width="19" align="left"><input name="scrollScreen" type="checkbox" class="noborder" id="scrollScreen" onClick="checkScrollScreen()" value= "1" checked></td> </tr> <tr> <td width="21" height="30" align="left"> </td> <td width="549" align="left"> <input name="content1" type="text" size="70" onKeyDown="if(event.keyCode==13 && event.ctrlKey){send();}"> <input name="Submit2" type="button" class="btn_grey" value="发送" onClick="send()"></td> <td align="right"><input name="button_exit" type="button" class="btn_grey" value="退出寝室圈" onClick="Exit()"></td> <td align="center"> </td> </tr> <tr> <td height="30" align="left"> </td> <td colspan="2" align="center" class="word_dark"> All CopyRights ? reserved 2016 江西师范大学工作室</td> <td align="center"> </td> </tr> </form> </table> </body> </html>
定义用户对象userInfo
package com.wgh.model; import java.util.Vector; public class UserInfo { private static UserInfo user = new UserInfo(); private Vector vector = null; // 利用private调用构造函数,防止被外界产生新的instance对象 private UserInfo() { this.vector = new Vector(); } // 外界使用的instance对象 public static UserInfo getInstance() { return user; } // 增加用户 public boolean addUser(String user) { if (user != null) { this.vector.add(user); return true; } else { return false; } } // 获取用户列表 public Vector getList() { return vector; } // 移除用户 public void removeUser(String user) { if (user != null) { vector.removeElement(user); } } }
MessageServlet做逻辑处理:
package com.wgh.servlet; import com.wgh.model.UserInfo; import java.io.*; import java.util.Date; import java.util.Random; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.*; public class Messages extends HttpServlet { /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); String action = request.getParameter("action"); if ("loginRoom".equals(action)) { //登录时,写入系统公告 this.loginRoom(request, response); } else if ("sendMessage".equals(action)) { //发送聊天信息 this.sendMessages(request, response); } else if ("getMessages".equals(action)) { //读取聊天信息 this.getMessages(request, response); } } // 将页面重定向到显示聊天信息的页面 public void getMessages(HttpServletRequest request,HttpServletResponse response) { response.setContentType("text/html;charset=UTF-8"); try { request.getRequestDispatcher("Chatcontent.jsp").forward(request, response); } catch (Exception ex) { Logger.getLogger(Messages.class.getName()).log(Level.SEVERE, null, ex); } } // 登录时,写入系统公告 public void loginRoom(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); HttpSession session = request.getSession(); String username=request.getParameter("username"); //获得登录用户名 UserInfo user=UserInfo.getInstance(); //获得UserInfo类的对象 session.setMaxInactiveInterval(600); //设置Session的过期时间为10分钟 Vector vector=user.getList(); boolean flag=true; //标记是否登录的变量 //判断用户是否登录 System.out.println("vector的size:"+vector.size()); if(vector!=null&&vector.size()>0){ for(int i=0;i<vector.size();i++){ System.out.println("vector"+i+":"+vector.elementAt(i)+" user:"+username); if(username.equals(vector.elementAt(i))){ PrintWriter out; try { out = response.getWriter(); out.println("<script language=‘javascript‘>alert(‘该用户已经登录‘);window.location.href=‘Chatindex.jsp‘;</script>"); } catch (IOException e) { e.printStackTrace(); } flag=false; break; } } } //保存用户信息 if(flag){ UserListener ul=new UserListener(); //创建UserListener的对象 ul.setUser(username); //添加用户 user.addUser(ul.getUser()); //添加用户到UserInfo类的对象中 session.setAttribute("user",ul); //将UserListener对象绑定到Session中 session.setAttribute("username",username); //保存当前登录的用户名 session.setAttribute("loginTime",new Date().toLocaleString()); //保存登录时间 ServletContext application=getServletContext(); String sourceMessage=""; if(null!=application.getAttribute("message")){ sourceMessage=application.getAttribute("message").toString(); } sourceMessage+="系统公告:<font color=‘gray‘>" + username + "进入了寝室圈!</font><br>"; application.setAttribute("message",sourceMessage); try { request.getRequestDispatcher("Chatlogin_ok.jsp").forward(request, response); } catch (Exception ex) { Logger.getLogger(Messages.class.getName()).log(Level.SEVERE, null, ex); } } } // 发送聊天信息 public void sendMessages(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); request.setCharacterEncoding("UTF-8"); Random random = new Random(); String from = request.getParameter("from"); //发言人 String face = request.getParameter("face"); //表情 String to = request.getParameter("to"); //接收者 String color = request.getParameter("color"); //字体颜色 String content = request.getParameter("content"); //发言内容 String sendTime = new Date().toLocaleString(); //发言时间 ServletContext application = getServletContext(); String sourceMessage = application.getAttribute("message").toString(); try { //发言时间 sourceMessage += "<font color=‘blue‘><strong>" + from + "</strong></font><font color=‘#CC0000‘>" + face + "</font>对<font color=‘green‘>[" + to + "]</font>说:" + "<font color=‘" + color + "‘>" + content + "</font>(" + sendTime + ")<br>"; application.setAttribute("message", sourceMessage); request.getRequestDispatcher("Messages?action=getMessages&nocache=" + random.nextInt(10000)).forward(request, response); } catch (Exception ex) { Logger.getLogger(Messages.class.getName()).log(Level.SEVERE, null, ex); } } // <editor-fold defaultstate="collapsed" desc="HttpServlet 方法。单击左侧的 + 号以编辑代码。"> /** * Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> }
监听在线的用户人数:
package com.wgh.servlet; import com.wgh.model.UserInfo; import javax.servlet.http.HttpSessionBindingEvent; public class UserListener implements javax.servlet.http.HttpSessionBindingListener { private String user; private UserInfo container = UserInfo.getInstance(); //获得UserInfo类的对象 public UserListener() { user = ""; } // 设置在线监听人员 public void setUser(String user) { this.user = user; } // 获取在线监听 public String getUser() { return this.user; } // 当Session有对象加入时执行的方法 public void valueBound(HttpSessionBindingEvent arg0) { System.out.println("上线用户:" + this.user); } // 当Session有对象移除时执行的方法 public void valueUnbound(HttpSessionBindingEvent arg0) { System.out.println("下线用户:" + this.user); if (user != "") { container.removeUser(user); } } }
客户端发起Ajax请求:
package com.wgh.servlet; import com.wgh.model.UserInfo; import javax.servlet.http.HttpSessionBindingEvent; public class UserListener implements javax.servlet.http.HttpSessionBindingListener { private String user; private UserInfo container = UserInfo.getInstance(); //获得UserInfo类的对象 public UserListener() { user = ""; } // 设置在线监听人员 public void setUser(String user) { this.user = user; } // 获取在线监听 public String getUser() { return this.user; } // 当Session有对象加入时执行的方法 public void valueBound(HttpSessionBindingEvent arg0) { System.out.println("上线用户:" + this.user); } // 当Session有对象移除时执行的方法 public void valueUnbound(HttpSessionBindingEvent arg0) { System.out.println("下线用户:" + this.user); if (user != "") { container.removeUser(user); } } }
web.xml配置
<session-config> <session-timeout> 30 </session-timeout> </session-config> <servlet> <servlet-name>Messages</servlet-name> <servlet-class>com.wgh.servlet.Messages</servlet-class> </servlet> <servlet-mapping> <servlet-name>Messages</servlet-name> <url-pattern>/Messages</url-pattern> </servlet-mapping> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.wgh.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list>
聊天页面:
项目总结:该项目实现了基本群聊功能,但是也存在如下缺陷:
(1)客户端发起Ajax请求来获取消息效率偏低,一旦用户过多,给服务器造成的压力很大。
(2)服务器关闭之后便会清除之前的聊天记录,应考虑将记录存入数据库,方便用户查看历史记录。
(3)技术交流请联系我:Q:1807533059
原文:http://www.cnblogs.com/litingshi/p/6249952.html