Listener 笔记记录
- 1. Listener监听器
- 2. 监听对象的监听器
- 2.1 ServletContetListener
- 2.2 HttpSessionListener
- 2.3 ServletRequestListener
- 3. 监听域对象属性变化的监听器
- 3.1 ServletContextAttributeListener
- 3.2 HttpSessionAttributeListener
- 3.3 ServletRequestAttributeListener
- 4. 监听会话相关的感知型监听器
- 4.1 HttpSessionBindingListener
- 4.2 HttpSessionActivationListener
- 5. 监听器的使用
- 5.1 ServletContextListener使用
- 5.2 ServletContextAttributeListener使用
- 6. Javaweb综合案例
- version 1.0
- version 2.0
1. Listener监听器
2. 监听对象的监听器
2.1 ServletContetListener
2.2 HttpSessionListener
2.3 ServletRequestListener
3. 监听域对象属性变化的监听器
3.1 ServletContextAttributeListener
3.2 HttpSessionAttributeListener
3.3 ServletRequestAttributeListener
4. 监听会话相关的感知型监听器
4.1 HttpSessionBindingListener
4.2 HttpSessionActivationListener
钝化与活化:
Session的活化和钝化
Session机制很好的解决了Cookie的不足,但是当访问应用的用户很多时,服务器上就会创建非常多的Session对象,如果不对这些Session对象进行处理,那么在Session失效之前,这些Session一直都会在服务器的内存中存在。那么就,就出现了Session活化和钝化的机制。
1)Session钝化:
Session在一段时间内没有被使用时,会将当前存在的Session对象序列化到磁盘上,而不再占用内存空间。
2)Session活化:
Session被钝化后,服务器再次调用Session对象时,将Session对象由磁盘中加载到内存中使用。
如果希望Session域中的对象也能够随Session钝化过程一起序列化到磁盘上,则对象的实现类也必须实现java.io.Serializable接口。不仅如此,如果对象中还包含其他对象的引用,则被关联的对象也必须支持序列化,否则会抛出异常:java.io.NotSerializableException
5. 监听器的使用
一共八个
5.1 ServletContextListener使用
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* ServletContext对象创建和销毁的监听器
*/
@WebListener
public class ListenerDemo implements ServletContextListener {
/**
* @Description ServletContext创建的时候执行
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了对象创建");
//获取对象
ServletContext servletContext = sce.getServletContext();
System.out.println(servletContext);
}
/**
* @Description ServletContext 销毁的时候执行
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听到了对象销毁");
//获取对象
ServletContext servletContext = sce.getServletContext();
System.out.println(servletContext);
}
}
5.2 ServletContextAttributeListener使用
除了使用@weblistener注解还可以在web.xml中配置监听器
下面两个监听器注解替换为web.xml中配置
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* ServletContext对象创建和销毁的监听器
*/
@WebListener
public class ListenerDemo implements ServletContextListener {
/**
* @Description ServletContext创建的时候执行
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了对象创建");
//获取对象
ServletContext servletContext = sce.getServletContext();
System.out.println(servletContext);
servletContext.setAttribute("username","zhngsan");
servletContext.setAttribute("username","lisi");
servletContext.removeAttribute("username");
}
/**
* @Description ServletContext 销毁的时候执行
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听到了对象销毁");
//获取对象
ServletContext servletContext = sce.getServletContext();
System.out.println(servletContext);
}
}
import javax.servlet.*;
import javax.servlet.annotation.WebListener;
/**
* 应用域对象中的属性变化的监听器
*/
@WebListener
public class ListenerAttributeDemo implements ServletContextAttributeListener {
//添加属性时候的监听
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
System.out.println("监听到了属性的添加...");
//获取应用域对象
Object username = event.getServletContext().getAttribute("username");
System.out.println(username);
}
//移除属性时候的监听
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
System.out.println("监听到了属性的移除...");
//获取应用域对象
Object username = event.getServletContext().getAttribute("username");
System.out.println(username);
}
//替换属性时候的监听
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
System.out.println("监听到了属性的替换...");
//获取应用域对象
Object username = event.getServletContext().getAttribute("username");
System.out.println(username);
}
}
6. Javaweb综合案例
version 1.0
之前实现:
首页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生管理系统首页</title>
</head>
<body>
<% Object username = session.getAttribute("username");
if (username == null) {
%>
<a href="/student/login.jsp">请登录</a>
<%} else {%>
<a href="/student/addStudent.jsp">添加学生</a>
<a href="/student/listStudentServlet">查看学生</a>
<%}%>
</body>
</html>
登录页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生登录</title>
</head>
<body>
<form action="/student/loginServlet" method="get" autocomplete="off">
用户名: <input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<button type="submit">登录</button>
</form>
</body>
</html>
登录页面请求处理
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 java.io.IOException;
@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取用户名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
//判断用户名
if (username==null||"".equals(username)){
//用户名为空 重定向到登录界面
resp.sendRedirect("/student/login.jsp");
return;
}
if (username.equals("zhufanzhi")&&password.equals("123")){
//不为空 存入会话域
HttpSession session = req.getSession();
session.setAttribute("username",username);
//重定向到首页jsp
resp.sendRedirect("/student/index.jsp");
}else {
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("用户名密码错误。请重新登录");
resp.setHeader("Refresh","2;URL=/student/login.jsp");
return;
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
添加学生页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>添加学生</title>
</head>
<body>
<form action="/student/addServlet" method="get" autocomplete="off">
姓名: <input type="text" name="username"><br>
年龄:<input type="number" name="age"><br>
分数:<input type="number" name="score"><br>
<button type="submit">保存</button>
</form>
</body>
</html>
实体类
public class Student {
private String username;
private int age;
private int score;
@Override
public String toString() {
return "Student{" +
"username='" + username + '\'' +
", age=" + age +
", score=" + score +
'}';
}
public Student() {
}
public Student(String username, int age, int score) {
this.username = username;
this.age = age;
this.score = score;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
添加学生请求处理
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 java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
@WebServlet("/listStudentServlet")
public class listStudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 创建字符输入流对象 关联读取文件
BufferedReader br=new BufferedReader(new FileReader("d:\\stu.txt"));
//2. 创建集合对象 用于保存Student对象
ArrayList<Student > list=new ArrayList<>();
//3.循环读取文件中的数据 将数据封装到Student 对象中 再把多个学生对象添加到集合中
String line;
while ((line=br.readLine())!=null){
// 张三 18 100
Student stu=new Student();
String[] arr = line.split(",");
stu.setUsername(arr[0]);
stu.setAge(Integer.parseInt(arr[1]));
stu.setScore(Integer.parseInt(arr[2]));
list.add(stu);
}
//4.遍历集合 将数据响应到浏览器
//获取输出流对象
resp.setContentType("text/html;charset=UTF-8");
// PrintWriter pw = resp.getWriter();
// for (Student s:list){
// pw.write(s.getUsername()+","+s.getAge()+","+s.getScore());
// pw.write("<br>");
// }
req.getSession().setAttribute("stus",list);
//5.重定向
resp.sendRedirect("/student/list.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
学生列表页面展示
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.example.student_manage.Student" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>查看学生</title>
</head>
<body>
<table width="600px" border="1px">
<tr>
<th>姓名</th>
<th>年龄</th>
<th>成绩</th>
</tr>
<% ArrayList<Student> students= (ArrayList<Student>) session.getAttribute("stus");
for (Student stu:students ){
%>
<tr>
<td><%=stu.getUsername()%></td>
<td><%=stu.getAge()%></td>
<td><%=stu.getScore()%></td>
</tr>
<%}%>
</table>
</body>
</html>
学生列表请求处理
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 java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
@WebServlet("/listStudentServlet")
public class listStudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 创建字符输入流对象 关联读取文件
BufferedReader br=new BufferedReader(new FileReader("d:\\stu.txt"));
//2. 创建集合对象 用于保存Student对象
ArrayList<Student > list=new ArrayList<>();
//3.循环读取文件中的数据 将数据封装到Student 对象中 再把多个学生对象添加到集合中
String line;
while ((line=br.readLine())!=null){
// 张三 18 100
Student stu=new Student();
String[] arr = line.split(",");
stu.setUsername(arr[0]);
stu.setAge(Integer.parseInt(arr[1]));
stu.setScore(Integer.parseInt(arr[2]));
list.add(stu);
}
//4.遍历集合 将数据响应到浏览器
//获取输出流对象
resp.setContentType("text/html;charset=UTF-8");
// PrintWriter pw = resp.getWriter();
// for (Student s:list){
// pw.write(s.getUsername()+","+s.getAge()+","+s.getScore());
// pw.write("<br>");
// }
req.getSession().setAttribute("stus",list);
//5.重定向
resp.sendRedirect("/student/list.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
version 2.0
优化1:使用过滤器配置全局中文乱码问题
优化2:将jspjava代码块改为EL表达式和JSTL
优化3:权限拦截实现,用户未登录不能进行操作
优化4:虚拟目录变为动态获取
优化1:
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 解决全局乱码问题
*/
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
//1. 将请求和响应对象转化未Http协议相关
HttpServletRequest httpServletRequest= (HttpServletRequest) request;
HttpServletResponse httpServletResponse= (HttpServletResponse) response;
//2.设置编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//3.放行
filterChain.doFilter(httpServletRequest,httpServletResponse);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
优化2:
<c:forEach items="${stus}" var="s">
<tr align="center">
<td>${s.username}</td>
<td>${s.age}</td>
<td>${s.score}</td>
</tr>
</c:forEach>
优化3:登录拦截
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 登录拦截请求
* 未登录 拦截addStudent页面和展示学生页面
**/
@WebFilter(value = {"/addStudent.jsp","/listStudentServlet"})
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//1. 将请求和响应对象转化未Http协议相关
HttpServletRequest request= (HttpServletRequest) servletRequest;
HttpServletResponse response= (HttpServletResponse) servletResponse;
//2. 拦截 获取会话域信息 判断用户名
Object username = request.getSession().getAttribute("username");
if (username==null||"".equals(username)){
//重定向到登录页面
response.sendRedirect(request.getContextPath()+"/login.jsp");
return;
}
//3. 放行
filterChain.doFilter(request,response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
优化4:
增加学生页面的请求改为动态虚拟路径
完整代码:
******************首页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>学生管理系统首页</title>
</head>
<body>
<%--*********************version 1.0--%>
<%--<% Object username = session.getAttribute("username");--%>
<%-- if (username == null) {--%>
<%--%>--%>
<%--<a href="/student/login.jsp">请登录</a>--%>
<%--<%–<%} else {%>–%>--%>
<%--<a href="/student/addStudent.jsp">添加学生</a>--%>
<%--<a href="/student/listStudentServlet">查看学生</a>--%>
<%--<%}%>--%>
<%--************************version 2.0--%>
<c:if test="${sessionScope.username eq null}">
<a href="${pageContext.request.contextPath}/login.jsp">请登录</a>
</c:if>
<c:if test="${sessionScope.username ne null}">
<a href="${pageContext.request.contextPath}/addStudent.jsp">添加学生</a>
<a href="${pageContext.request.contextPath}/listStudentServlet">查看学生</a>
</c:if>
</body>
</html>
******************登录页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/loginServlet" method="get" autocomplete="off">
用户名: <input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<button type="submit">登录</button>
</form>
</body>
</html>
******************登录请求处理
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 java.io.IOException;
@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取用户名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
//判断用户名
if (username==null||"".equals(username)){
//用户名为空 重定向到登录界面
resp.sendRedirect("/student/login.jsp");
return;
}
if (username.equals("zhufanzhi")&&password.equals("123")){
//不为空 存入会话域
HttpSession session = req.getSession();
session.setAttribute("username",username);
//重定向到首页jsp
resp.sendRedirect("/student/index.jsp");
}else {
// resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("用户名密码错误。请重新登录");
resp.setHeader("Refresh","2;URL=/student/login.jsp");
return;
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
***************************添加学生页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>添加学生</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/addServlet" method="get" autocomplete="off">
姓名: <input type="text" name="username"><br>
年龄:<input type="number" name="age"><br>
分数:<input type="number" name="score"><br>
<button type="submit">保存</button>
</form>
</body>
</html>
**************************添加学生请求处理
@WebServlet("/addServlet")
public class addStudent extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取表单数据
String username = req.getParameter("username");
String age = req.getParameter("age");
String score = req.getParameter("score");
//2. 创建学生对象并赋值
Student student = new Student(username, Integer.parseInt(age), Integer.parseInt(score));
//3.将学生对象的数据保存到d:\\stu.txt
BufferedWriter bw=new BufferedWriter(new FileWriter("d:\\stu.txt",true));
bw.write(student.getUsername()+","+student.getAge()+","+student.getScore());
bw.newLine();
bw.close();
//4.通过定时刷新功能响应给浏览器
// resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("添加成功。2秒后自动跳转到首页");
resp.setHeader("Refresh","2;URL=/student/index.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
*****************************展示学生页面
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.example.student_manage.bean.Student" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>查看学生</title>
</head>
<body>
<%--*************************** version 1.0 --%>
<%--<table width="600px" border="1px">--%>
<%-- <tr>--%>
<%-- <th>姓名</th>--%>
<%-- <th>年龄</th>--%>
<%-- <th>成绩</th>--%>
<%-- </tr>--%>
<%-- <% ArrayList<Student> students= (ArrayList<Student>) session.getAttribute("stus");--%>
<%-- for (Student stu:students ){--%>
<%-- %>--%>
<%-- <tr>--%>
<%-- <td><%=stu.getUsername()%></td>--%>
<%-- <td><%=stu.getAge()%></td>--%>
<%-- <td><%=stu.getScore()%></td>--%>
<%-- </tr>--%>
<%-- <%}%>--%>
<%--</table>--%>
<%--*************************** version 2.0 --%>
<table width="600px" border="1px">
<tr>
<th>学生姓名</th>
<th>学生年龄</th>
<th>学生成绩</th>
</tr>
<%--items 中为后端传来的数据 var 代表遍历买一个元素--%>
<c:forEach items="${stus}" var="s">
<tr align="center">
<td>${s.username}</td>
<td>${s.age}</td>
<td>${s.score}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
*****************************展示学生页面请求处理
import com.example.student_manage.bean.Student;
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 java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
@WebServlet("/addServlet")
public class addStudent extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取表单数据
String username = req.getParameter("username");
String age = req.getParameter("age");
String score = req.getParameter("score");
//2. 创建学生对象并赋值
Student student = new Student(username, Integer.parseInt(age), Integer.parseInt(score));
//3.将学生对象的数据保存到d:\\stu.txt
BufferedWriter bw=new BufferedWriter(new FileWriter("d:\\stu.txt",true));
bw.write(student.getUsername()+","+student.getAge()+","+student.getScore());
bw.newLine();
bw.close();
//4.通过定时刷新功能响应给浏览器
// resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("添加成功。2秒后自动跳转到首页");
resp.setHeader("Refresh","2;URL=/student/index.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
************************过滤器配置上述