使用Servlet和JSP实现一个简单的Web聊天室系统
目录
1 问题描述
1 问题描述
利用Java EE相关技术实现一个简单的Web聊天室系统,具体要求如下。
(1)编写一个登录页面,登录信息中有用户名和密码,分别用两个按钮来提交和重置登录信息。
(2)编写一个Servlet程序Main.java通过请求指派来处理用户提交的登录信息,如果用户名为本小组成员的名字且密码为对应的学号时,跳转到LoginSuccess显示聊天界面(类似于QQ群聊天界面,可使用HTML中的frameset标签生成两个窗口,一个用来实现用户信息输入,另一个显示所有用户聊天记录的);否则跳转到LoginFail页面,提示用户重新登录(注:此页面要包含前面的登录界面)。
(3)编写两个Servlet程序,分别用来显示“信息输入”窗口和“聊天记录显示”窗口的内容;用户在“信息输入”窗口中键入聊天内容,点击“发送”按钮后,在“聊天记录显示”窗口中显示发送消息的用户名称和聊天内容。提示:利用HTML中的textarea标签来实现。
(4)在登录界面上实现记住用户名和密码的功能,使得当用户选择了此功能并成功登录后,在其下次登录时可以不用再输入用户名和密码即可登录。提示:此功能可通过两个Cookie来实现。
以下功能选做:
(5)编写一个Listener程序来监听会话的创建和销毁事件,以此统计当前在线(登录)人数,并将其显示在聊天界面上。
(6)添加一个Filter对本系统所有的Servlet程序进行过滤,该Filter实现对请求和响应对象的编码格式的设置(实现此功能后,Servlet可以直接从请求对象中获取参数信息而无需实现对请求进行格式的编码)。在【GlassFish Server】视图中输出程序在Filter和其它资源之间的执行顺序。
2 解决方案
2.1 预期效果
图一:网上聊天系统运行示意图
2.2 系统结构示意图
图二:系统结构示意图
具体解释:
(1)打开浏览器,进入网上聊天系统首页登录界面login.jsp。输入用户名和密码,点击登陆;
(2)Main.java类获取login.jsp用户输入的用户名和密码,进行逻辑验证,验证成功则跳转到聊天界面welcome.jsp,否则跳转到登陆失败提示界面loginFail.jsp;
(3)Welcome.jsp聊天界面,其中头部界面显示当前登陆用户昵称和当前在线总人数(统计当前在线人数通过调用OnlineListener类来实现);左部为聊天好友列表界面,此处仅作展示页面,未写具体逻辑处理代码;中间主体页面main.jsp页面实现用户在聊天输入框中输入消息,发送并显示在聊天消息显示框中功能。(实现聊天功能通过调用InputInformation.java类来实现)具体页面如下图所示:
图三:聊天页面welcome.jsp
图三:welcome.jsp实际运行图
2.3 具体编码
(1)Main.java(Servlet类)通过请求指派来处理login.jsp页面用户提交的登录信息(并使用Cookie实现记住用户登录用户名和密码功能),成功则跳转到welcome.jsp,失败则跳转到loginFail.jsp。具体实现如下:
网上聊天系统登陆首页login.jsp页面代码:
注意:此处代码有点问题,感谢文末园友指正,具体如下:
login.jsp页面代码:Cookie[] cookies = request.getCookies();
开启服务第一次登录时是没有cookie的,所以执行 for (int i = 0; i < cookies.length; i++) 时会出现空指针异常。在for循环前加个if判断:if(cookies!=null)才能成功运行
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; String username = ""; String password = ""; //String[] checkBox = request.getParameterValues("save_password"); //获取当前站点的所有Cookie Cookie[] cookies = request.getCookies(); for (int i = 0; i < cookies.length; i++) { //对cookies中的数据进行遍历,找到用户名、密码的数据 if ("username".equals(cookies[i].getName())) { //读取时URLDecoder.decode进行解码(PS:Cookie存取时用URLEncoder.encode进行编码) username = java.net.URLDecoder.decode(cookies[i].getValue(),"UTF-8"); } else if ("password".equals(cookies[i].getName())) { password = java.net.URLDecoder.decode(cookies[i].getValue(),"UTF-8"); } } %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>网上聊天室登陆页面</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <style type="text/css"> * { margin: 0; padding: 0; } body { font-size: 0px; padding: 200px; } </style> </head> <body> <form action="Main" method="post"> <div style="background:#49AFFF;font-size: 80px;text-align:center;">网上聊天室</div> <div style="background:#75FFE7;font-size: 35px;text-align:center;"> <span>用户名:</span><input type="text" name="username" value="<%=username%>" style="border:1px solid #ccc; 400px; height:40px;" ></div> <div style="background:#75FFE7;font-size: 35px;text-align:center;"> <span>密 码 :</span><input type="password" name="password" value="<%=password%>" style="border:1px solid #ccc; 400px; height:40px;" ></div> <div style="background:#75FFE7;font-size: 25px;text-align:center;"> <input type="checkbox" value="save" name="save_password">记住密码 <input type="submit" value="登陆" name="login" style=" 100px; height: 40px;font-size: 30px;"> <input type="reset" value="重置" name="reset" style=" 100px; height: 40px;font-size: 30px;"></div> </form> </body> </html>
Main.java类代码:
package com.liuzhen.chart; import java.io.IOException; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class Main extends HttpServlet { /** * Constructor of the object. */ public Main() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //response.setContentType("text/html;charset=utf-8"); //此出注解是因为使用CodeFilter类过滤所有Servlet,转换编码 //request.setCharacterEncoding("utf-8"); String userName = request.getParameter("username"); String passWord = request.getParameter("password"); String checkBox = request.getParameter("save_password"); System.out.println("userName:"+userName+" "+"passWord:"+passWord); request.getSession().setAttribute("nameSession", userName); //将用户名存入session中 String[] name_one = {"柳真","刘仁杰","吴超","张浩东","陈初相"}; String[] pwd_one = {"201421092073","201421092068","201421092077","201421092082","201421092119"}; String name_two = ""; String pwd_two = ""; boolean login_test = false; for(int i=0;i<5;i++){ name_two = name_one[i]; pwd_two = pwd_one[i]; if(userName.equals(name_two) && passWord.equals(pwd_two)) login_test = true; } if(login_test) { if ("save".equals(checkBox)) { //Cookie存取时用URLEncoder.encode进行编码(PS:读取时URLDecoder.decode进行解码) String name = URLEncoder.encode(userName,"UTF-8"); //创建两个Cookie对象 Cookie nameCookie = new Cookie("username", name); //设置Cookie的有效期为3天 nameCookie.setMaxAge(60 * 60 * 24 * 3); String pwd = URLEncoder.encode(passWord,"UTF-8"); Cookie pwdCookie = new Cookie("password", pwd); pwdCookie.setMaxAge(60 * 60 * 24 * 3); response.addCookie(nameCookie); response.addCookie(pwdCookie); } request.getRequestDispatcher("welcome.jsp").forward(request, response); } else{ response.sendRedirect("loginFail.jsp"); // request.getRequestDispatcher("loginFail.jsp").forward(request, response); } } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } }
登陆失败页面loginFail.jsp页面代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'loginFail.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="content-type" content="text/html; charset=gb2312"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <br> <br> <h1>用户名和密码不匹配,请重新登陆!</h1> <a href="login.jsp">重新登陆</a> </body> </html>
登陆成功页面welcome.jsp页面代码(此处使用frameset标签,分为头部、左部和中间主页三部分,分别对象header.jsp、left.jsp和main.jsp页面):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>网上聊天室</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="content-type" content="text/html; charset=gb2312"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <frameset rows="100,*" cols="*" frameborder="no" border="0" framespacing="0"> <frame src="header.jsp" name="topFrame" scrolling="auto" noresize="noresize" /> <frameset cols="213,*" frameborder="no" border="0" framespacing="0"> <frame src="left.jsp" name="leftFrame" scrolling="No" noresize="noresize" /> <frame src="main.jsp" name="mainFrame" scrolling="auto" /> </frameset> </frameset> <body> </body> </html>
聊天头部header.jsp页面代码:
<%@ page language="java" import="java.util.*" contentType="text/html;charset=gb2312" pageEncoding="gb2312"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title></title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <meta http-equiv="Content-Type" content="text/html;charset=gb2312"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body topmargin="0" leftmargin="0" rightmargin="0"> <form action=""> <table width="100%" height="79" border="0" cellpadding="0" cellspacing="0" align=center> <tr> <td bgcolor="F9A859" valign="top"> <table width="100%" height="50" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="FBEAD0"> <tr> <td align="center" style="font-size:40px;"> 网上聊天室 </td> </tr> </table> </td> </tr> <tr> <td bgcolor="F9A859" valign="top"> <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td align="center" style="font-size:20px" valign="middle"> 欢迎<%=(String)request.getSession().getAttribute("nameSession") %>访问! 当前在线人数为<%=application.getAttribute("peopleOnline")%>人 </td> </tr> </table> </td> </tr> </table> </form> </body> </html>