用Servlet实现聊天室设计

实验一   Servlet编程

一.实验目的

1.熟悉Java EE编程环境JDK和NetBeans的安装,配置和使用;

2.掌握Servlet的编写及部署;

3.掌握Servlet的工作原理和编程接口;

4.掌握Servlet中客户端输入数据处理技术;

5.掌握Servlet中的会话跟踪技术;

6.掌握Servlet中的请求指派技术;

7.掌握Servlet上下文属性的使用方法;

8.掌握Servlet中Filter基本编程技术;

9.掌握Servlet中Listener基本编程技术;

二.实验内容利用JavaEE相关技术实现一个简单的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和其它资源之间的执行顺序。

本次例子重在思路,页面未做任何美化。关于包文件的引用一定要注意,Servlet需要引入相应的包文件才能运行,一般IDE都会自动创建引入,这里不做解释

1.首先,需要一个登陆页面。LoginServlet

 package com.jun.servlet;

 import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();//获取cookie对象
String uname = "";
String upwd = "";
if (cookies != null) {
for (int i = ; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookie.getName().equals("remname")) {
uname = cookie.getValue();
} else if (cookie.getName().equals("rempwd")) {
upwd = cookie.getValue();
}
}
}
//上面代码用来判断用户是否曾保存过登陆信息 response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<html><head><title>登陆界面</title>");
out.println("<body>");
out.println("<div>");
out.println("<form action='Main' method='post'");
out.println("<p>用户名:<input type='text' name='username' value=" +uname+ "></p>");
out.println("<p>密 码:<input type='password' name='password' value=" +upwd+ "></p>");
out.println("<p>记住密码:<input type='checkbox' name='remember' value='true'>");
out.println("<input type='submit' name='submit' value='登陆'>");
out.println("<input type='reset' name='reset' value='重置'></p>");
out.println("</div>");
out.println("</body></html>");
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

2.新建一个用来处理登录信息的Servlet: Main.java 所有的处理都在DoPost()完成

 package com.jun.servlet;

 import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; /**
* Servlet implementation class Main
*/
@WebServlet(name = "Main", urlPatterns = { "/Main" })
public class Main extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public Main() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String username, password, remember;
HttpSession session = request.getSession(true);//开启会话 username = (String) request.getParameter("username");
password = (String) request.getParameter("password");
remember = (String) request.getParameter("remember");
//在控制台中输出,方便审查
System.out.println("remember:" + remember);
System.out.println(username);
System.out.println(password); if (username != null && username.equals("") && password.equals("")) {
if (remember != null && remember.equals("true")) {
Cookie cookie1 = new Cookie("remname", username);
Cookie cookie2 = new Cookie("rempwd", password);
cookie1.setMaxAge( * * * );
cookie2.setMaxAge( * * * ); response.addCookie(cookie1);
response.addCookie(cookie2);
}
session.setAttribute("UserName", username);
session.setAttribute("IsLogin", "true");
response.sendRedirect("LoginSuccessServlet");//用sendRedirect实现页面完全跳转
} else if (username != null && username.equals("") && password.equals("")) {
if (remember != null && remember.equals("true")) {//当用户勾选记住密码功能时,将密码返回给客户端保存,下次访问的时候先从客户端获取密码,这样就实现了记住密码功能
Cookie cookie1 = new Cookie("remname", username);
Cookie cookie2 = new Cookie("rempwd", password);
cookie1.setMaxAge( * * * );
cookie2.setMaxAge( * * * );
response.addCookie(cookie1);
response.addCookie(cookie2);
}
session.setAttribute("UserName", username);
session.setAttribute("IsLogin", "true");
response.sendRedirect("LoginSuccessServlet");
} else {
session.setAttribute("IsLogin", "false");
response.sendRedirect("LoginFail.html");//页面完全跳转,不会出现乱码
}
} }

3.登陆成功,就实现页面跳转 LoginSuccessServlet

 package com.jun.servlet;

 import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSession; /**
* Servlet implementation class LoginSuccessServlet
*/
@WebServlet("/LoginSuccessServlet")
public class LoginSuccessServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public LoginSuccessServlet() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
HttpSession session = request.getSession();//
String username = "";
if (session.getAttribute("UserName") != null) {
username = session.getAttribute("UserName").toString();
} PrintWriter out = response.getWriter();
out.println("<html><head><title>聊天室</title>");
out.println("<style type='text/css'>#iframe1{width:600px;height:200px;}iframe{width:600px;height:200px;margin-bottom:20px;}</style>");
out.println("</head>");
out.println("<center><h2><b>欢迎使用聊天系统</b></h2>");
out.println("<lable>当前用户:" + username
+ "</lable><a href=\"LoginOut\"> 退出登录</a><br>");
out.println("<iframe src='Messagebox' id='iframe1'></iframe>");
out.println("<br>");
out.println("<iframe src='Talk'></iframe><br>");
/*out.println("<frameset rows=\"50%,25%\">");
out.println("<frame name=\"message\" src=\"Messagebox\" />");
out.println("<frame name=\"uinput\" src=\"Talk\"/>");
out.println("</frameset>");
*/
out.println("</body></html>"); } /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub } }

4.登录失败,跳转到失败页面

LoginFail.html
 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta http-equiv="refresh" content ="3;url=LoginServlet">
</head>
<body>
<b>呦呦呦,登陆失败了哟,3秒后跳转到登录页重新登陆哟! <a href="LoginServlet">点击此处直接跳转</a></b>
</body>
</html>

5.登录成功的页面中用frame嵌入了两个页面,分别显示用户的信息输入(Talk)和显示(Messagebox)。

下面为Talk的页面

 package com.jun.servlet;

 import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; /**
* Servlet implementation class Talk
*/
@WebServlet("/Talk")
public class Talk extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public Talk() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String username = (String) session.getAttribute("UserName");// 将获取的对象强制类型转换为字符串 out.println("<html><body>");
out.println("<lable>当前用户:" + username + "</lable><br>");
out.println("<form action=\"Talk\" method=\"post\">");
out.println("<div><textarea name=\"userMessages\" cols=\"50\" style=\"height:100px;\"></textarea></div>");
out.println("<div><input type=\"submit\" id=\"submit\" value=\"发送\"/>");
out.println("<input type=\"reset\" id=\"reset\" value=\"清空输入\"/></div>");
out.println("</form>");
out.println("</body></html>");
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
HttpSession session = request.getSession();
ServletContext application = this.getServletContext();// 获取上下文信息 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 日期格式
Date currentTime = new Date();// 得到当前的系统时间
String str_date1 = formatter.format(currentTime);// 将日期时间格式化 str_date1
String username = (String) session.getAttribute("UserName");// 将获取的对象强制类型转换为字符串 PrintWriter out = response.getWriter(); String mywords = request.getParameter("userMessages");// 获取提交信息的内容
// mywords
application.log(mywords);// 在控制台中将提交的内容显示出来
if (mywords == null) {
mywords = "系统提示:可以聊天";
application.setAttribute("words", mywords + "\n");
} else if (mywords != null) {
// int len_mywords = mywords.length();
// application.log("字节长度:"+len_mywords);
mywords = username + ":" + mywords + ":" + str_date1;// 给内容添上其他信息。
application.log(mywords);//在控制台信息中查看内容
Object obj = application.getAttribute("words");// 上下文获取 的都是一个对象
if (obj == null) {
application.setAttribute("words", mywords + "\n");// 设置成全局变量
} else {
application.setAttribute("words", obj.toString() + mywords
+ "\n");// 当获取的上下文对象不为空时,需要将前面的信息也显示出来
}
} out.println("<html><body>");
out.println("<lable>当前用户:" + username + "</lable><br>");
out.println("<form action=\"Talk\" method=\"post\">");
out.println("<div><textarea name=\"userMessages\" cols=\"50\" style=\"height:100px;\"></textarea></div>");
out.println("<div><input type=\"submit\" id=\"submit\" value=\"发送\"/>");
out.println("<input type=\"reset\" id=\"reset\" value=\"清空输入\"/></div>");
out.println("</form>");
out.println("</body></html>"); } }

6.Messagebox的页面

 package com.jun.servlet;

 import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; /**
* Servlet implementation class Messagebox
*/
@WebServlet("/Messagebox")
public class Messagebox extends HttpServlet {
private static final long serialVersionUID = 1L; protected void processRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
try { String temp = (String) getServletConfig().getServletContext()
.getAttribute("online");
if (temp == null)
temp = "";
ServletContext application = this.getServletContext();// 获取上下文信息
String words = (String) application.getAttribute("words");//上写文获取的变量都是对象,因此要进行强制类型转换之后才能使用 out.println("<html>");
out.println("<head>");
out.println("<title>Servlet messagebox</title>");
out.println("<meta http-equiv=\"refresh\" content =\"2;url=Messagebox\">");
out.println("</head>");
out.println("<body>");
out.println("<p>当前在线:");
out.println(temp);
out.println("人</p>");
out.println("<textarea name=\"messagebox\" cols=\"100\" words=\"400\" style=\"height:400px;\">");
out.println(words);
out.println("</textarea>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
} @Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
} @Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
} @Override
public String getServletInfo() {
return "Short description";
}// </editor-fold> }

7。用户点击退出之后,调用LoginOut.代码如下

 package com.jun.servlet;

 import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; /**
* Servlet implementation class LoginOut
*/
@WebServlet("/LoginOut")
public class LoginOut extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public LoginOut() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.removeAttribute("UserName");
//session.setAttribute("IsLogin", "false");
PrintWriter out = response.getWriter();
/*response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");*/ out.println("<html><head><title>注销登陆</title>");
out.println("<meta http-equiv=\"refresh\" content =\"1;url=LoginServlet\"></head>");
out.println("<body>bye-----bye!!!!</body>");
out.println("</html>");
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

8.过滤器的使用,在此例子中运用过滤器对所有页面的字符集进行过滤。FirstFilter的代码如下

 package com.jun.servlet;

 import java.io.IOException;

 import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; //WebFilter 3.0的特性 过滤器的名称为FirstFilter,过滤的对象为所有的页面urlPatterns={"/*"} ,必须要有 / 号
@WebFilter(filterName="FirstFilter",urlPatterns={"/*"})
public class FirstFilter implements Filter { @Override
public void destroy() {
System.out.println("destroy---FirstFilter");
} @Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
System.out.println("start----doFilter--FirstFilter"); HttpServletRequest request =(HttpServletRequest) arg0;
HttpServletResponse response =(HttpServletResponse) arg1;
//以上是强制内型转换,使用request对象和response对象 request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
arg2.doFilter(arg0, arg1);//在页面跳转之前执行此语句前面的代码,执行完页面的代码之后,在执行后面的语句
System.out.println("第一个字符过滤器");
System.out.println("end------doFilter--FirstFilter军军"); } @Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init----FirstFilter 军军");
} }

9.监听器的使用,我们需要对当前在线人数进行一个监听,实现的是HttpSessionListener,HttpSessionAttributeListener的接口

 package com.jun.servlet;

 import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//监听器的注解使用方法是直接用一个注解就行,然后就是创建类实现监听器的接口,覆盖监听器的方法,实现应用中的逻辑
@WebListener("这是一个用户信息监听器")
public class SessionListenr implements HttpSessionListener,
HttpSessionAttributeListener {
//监听器实现的两个接口,用于监听在线人数
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
if(event.getName().equals("UserName"))
{
String current = (String) event.getSession().getServletContext().getAttribute("online");//获取当前用户人数
String info = (String) event.getSession().getServletContext().getAttribute("Words");//当前用户的信息
if(info==null)info ="";
if(current == null) current="";
int c=Integer.parseInt(current);
c++;
current = String.valueOf(c);
event.getSession().getServletContext().setAttribute("online", current);
//event.getSession().getServletContext().setAttribute("Words", info+event.getValue()+" 加入聊天室\n");
} } @Override
public void attributeRemoved(HttpSessionBindingEvent event) {
if(event.getName().equals("UserName"))
{
String current = (String) event.getSession().getServletContext().getAttribute("online");
String info = (String) event.getSession().getServletContext().getAttribute("Words");
if(info==null)info ="";
if(current==null)current = "";
int c = Integer.parseInt(current);
c--;
current = String.valueOf(c);
event.getSession().getServletContext().setAttribute("online", current);
event.getSession().getServletContext().setAttribute("Words", info+event.getValue()+" 离开了聊天室\n");
} } @Override
public void attributeReplaced(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub } @Override
public void sessionCreated(HttpSessionEvent event) { /* String current = (String) event.getSession().getServletContext().getAttribute("online");//获取当前用户人数
if(current == null) current="0";
int c=Integer.parseInt(current);
c++;
current = String.valueOf(c);
event.getSession().getServletContext().setAttribute("online", current);*/ } @Override
public void sessionDestroyed(HttpSessionEvent event) { /* String current = (String) event.getSession().getServletContext().getAttribute("online");//获取当前用户人数
if(current == null) current="0";
int c=Integer.parseInt(current);
c++;
current = String.valueOf(c);
event.getSession().getServletContext().setAttribute("online", current);*/ } }

至此,一个简单的聊天室就完成了,下面是运行截图

用Servlet实现聊天室设计

用Servlet实现聊天室设计

上一篇:Openjudge-计算概论(A)-短信计费


下一篇:Python高手之路【十二】面向对象设计模式