工作室项目之寝室群聊的实现
登录页面: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请求:
var net=new Object(); //定义一个全局变量net
//编写构造函数
net.AjaxRequest=function(url,onload,onerror,method,params){
this.req=null;
this.onload=onload;
this.onerror=(onerror) ? onerror : this.defaultError;
this.loadDate(url,method,params);
}
//编写用于初始化XMLHttpRequest对象并指定处理函数,最后发送HTTP请求的方法
net.AjaxRequest.prototype.loadDate=function(url,method,params){
if (!method){
method="GET";
}
if (window.XMLHttpRequest){
this.req=new XMLHttpRequest();
} else if (window.ActiveXObject){
this.req=new ActiveXObject("Microsoft.XMLHTTP");
}
if (this.req){
try{
var loader=this;
this.req.onreadystatechange=function(){
net.AjaxRequest.onReadyState.call(loader);
}
this.req.open(method,url,true);
if(method=="POST"){
this.req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//设置提交数据的内容格式
}
this.req.send(params);
}catch (err){
this.onerror.call(this);
}
}
}
//重构回调函数
net.AjaxRequest.onReadyState=function(){
var req=this.req;
var ready=req.readyState;
if (ready==4){
if (req.status==200 ){
this.onload.call(this);
}else{
this.onerror.call(this);
}
}
}
//重构默认的错误处理函数
net.AjaxRequest.prototype.defaultError=function(){
alert("错误数据\n\n回调状态:"+this.req.readyState+"\n状态: "+this.req.status);
}
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)编辑器还比较原始,后期会加入CK编辑器等实现发送表情,上传图片等功能。
(4)技术交流请联系我:Q:1807533059

浙公网安备 33010602011771号