文章目录
一、题目
利用Java EE相关技术实现一个简单的Web聊天室系统,具体要求如下:
- 编写一个登录页面,登录信息中有用户名和密码,分别用两个按钮来提交和重置登录信息。
- 通过请求指派来处理用户提交的登录信息,如果用户名为本小组成员的名字且密码为对应的学号时,跳转到LoginSuccess显示聊天界面(类似于QQ群聊天界面,可使用HTML中的frameset标签生成两个窗口,一个用来实现用户信息输入,另一个显示所有用户聊天记录的);否则跳转到LoginFail页面,提示用户重新登录(注:此页面要包含前面的登录界面)。
- 在聊天室界面显示“信息输入”窗口和“聊天记录显示”窗口的内容;用户在“信息输入”窗口中键入聊天内容,点击“发送”按钮后,在“聊天记录显示”窗口中显示发送消息的用户名称和聊天内容(提示:可以利用Servlet 上下文保存聊天记录并将其显示在textarea中。)
- 在登录界面上实现记住用户名和密码的功能,使得当用户选择了此功能并成功登录后,在其下次登录时可以不用再输入用户名和密码即可登录(提示:此功能可通过Cookie来实现。)
以下功能选做:
- 编写一个Listener程序来监听会话的创建和销毁事件,以此统计当前在线(登录)人数,并将其显示在聊天界面上。
- 添加一个Filter对本系统所有的Servlet程序进行过滤,该Filter实现对请求和响应对象的编码格式的设置(实现此功能后,Servlet可以直接从请求对象中获取参数信息而无需实现对请求进行格式的编码)。在【GlassFish Server】视图中输出程序在Filter和其它资源之间的执行顺序。
二、实验环境
- JDK 1.8 提取码:gehi
- NetBeans IDE 8.1 提取码:4oe2
三、实现
1、流程图
2、界面效果
(1)登录界面效果
(2)聊天界面效果
因为写的简单,所以如果需要登录两个用户,需要在两个浏览器上登录。
3、具体界面
(1)登录界面(login.jsp)
1.1 jsp
- 获取所有的Cookie信息,当cookies不为空时,遍历获取用户名和密码,为了防止出现乱码,需要将用户名用 URLDecoder.decode(cookies[i].getValue(), “UTF-8”)方法解码。
1.2 表单
- 用户名框:
将input的placeholder属性设置为“请输入用户名”可将提示内容显示在输入框中;value设为<%=username%>可以在记住用户名后,刷新页面后能够自动填入用户名信息;name属性设为“username”方便后面取出用户名框中的值。 - 密码框:密码框与用户名框一致,将placeholder、value、type、name的值改为对应的值即可;
- 记住密码:input的type设为“checkbox”,即为复选框;value设为“yes”,用来标识是否勾选记住密码复选框;name设为“remember_pwd”;
- 重置按钮:在表单中将button的type属性设为“reset”,即可重置输入的内容;
- 登录按钮:在表单中将button的type属性设置为“submit”,在页面点击登录按钮时,会以post方法将表单内容提交到GetPostData。
(2)接收登录界面数据(GetPostData.java)
- 编码格式使用Filter过滤,所以不再重新设置编码格式;
- 利用request.getParameter方法从表单中获取用户名、密码和checkbox的值;创建usernameCookie和passwordCookie,因为用户名可能为中文,所以在创建usernameCookie时,我们需要用URLEncoder.encode()方法进行编码;
- 将小组成员的信息存入name和pwd数组中,遍历数组与获取的用户信息进行比较,如果在数组中找到对应的用户名密码则将用户名则用request.getSession().setAttribute()方法将用户名存入session中,将juge设为true,跳出循环;
- 如果用户名密码对应(即juge值为true),再判断用户是否在登录界面上勾选记住密码复选框,即通过request.getParameter(“remember_pwd”)获取的值与“yes比较”,如果为“yes”则设置MaxAge为一个月,否则设为0,然后将usernameCookie和pwdCookie添加到cookie信息中,最后通过sendRedirect方法跳转至登录成功界面;若juge值为false则跳到登录失败页面,并提示登录失败,然后跳转至登录界面重新登录。
(3)输入聊天内容(Input.java)
- 与其他页面一样,编码格式使用Filter过滤,所以不再重新设置编码格式;
- 用Date获取当前系统时间,将获取的时间转化为SimpleDateFormat设置的时间格式“MM-dd HH:mm”;
- 获取表单中name属性为input的值作为内容,并判断内容是否为空;若为空则弹出提示框提示内容不能为空,若不为空则通过request.getSession().getAttribute()方法获取当前用户的名字,并判断值是否为空;若为空则则提示重新登录,若不为空则将用户名字、时间和输入的内容组合作为聊天的内容储存;
- 将聊天内容通过getServletContext().setAttribute(“record”,chat_record)方法放入上下文中。
(4)输出聊天记录(output,jsp)
- 用request.getServletContext().getAttribute(“record”)方法获取聊天记录,判断内容是否为空;若为空则将record的值赋为” ”,避免在没有聊天记录时在聊天界面输出null;
- 同获取聊天记录一样获取在线人数,如果获取的聊天人数值为null,则将在线人数online赋值为0;
- 利用输出表达式<%=online%>和<%=record%>,将在线人数和聊天内容输在在输出聊天记录界面。
(5)拦截非法登录(LoginFilter.java)
- 在loginSuccess.html设置过滤器,用req.getSession().getAttribute(“nameSession”)方法获取在登录界面存的用户名session,判断session中是否为空,如果为空则提示未登录然后返回登录界面;如果不为空则执行chain.doFilter(request,response)语句,继续向下执行。
(6)监听在线人数(SessionListener.java)
- 用户登录,用户名密码正确提交后在接收登录界面数据的GetPostData.java中创建session。用户登录时,创建session调用sessionCreated,用evt.getSession().getServletContext().
getAttribute(“online”)方法获取当前人数current,如果为null则修改current为“0”,转化为整型,然后将人数加1,转化为字符串后再用evt.getSession().getServletContext().setAttribute
(“online”,current);将当前人数current写入。 - 用户登录后,点击聊天成员后面的注销按钮时,跳转至logout.jsp页面,调用request.getSession().invalidate();方法销毁会话,再通过sendRedirect方法跳转回聊天成员界面;调用sessionDestroyed,先获取当前在线人数current,转化为整型,人数减1,转化为字符串后再将会当前人数current人数写入。