监听器的概述
1.什么是监听器
监听器是实现了一个特定接口的Java类,这个java类用于监听另一个java类的方法或者属性的改变,当监听器对象发送上诉事件后,监听器某个方法将会立即被执行。
2.监听器的用途
用来监听其他对象的变化,主要用于图形化界面开发上
Java中的GUI,android。
3.监听器的术语
事件源:指的是被监听的对象
监听器:指的是监听的对象
绑定:事件源绑定监听器
事件:指的是事件源对象的改变—获取事件源对象
4.监听器的执行过程
Servlet中的监听器
在servlet中定义了多种类型的监听器,它们用于监听的事件源分别是,servletContext,HttpSession和ServletRequest这三个域对象。
1.Servlet中的监听器的分类
三类:
第一类:监听三个域对象的创建和销毁的监听器(三个)
第二类:监听三个域对象的属性变更(属性添加,移出,替换)的监听器(三个)
第三类:监听HttpSession中javaBean的状态改变(钝化,活化,绑定,解除绑定)的监听(两个)
第一类
ServletContextListener监听器的使用
用来监听servletcontext域对象的创建和销毁的监听器
ServletContext的创建和销毁
创建:在服务器启动时为每个web应用创建单独的servletcontext对象
销毁:在服务器关闭的时候,或者项目从web服务器移出的时候
ServletContextListener监听器的方法
监听ServletContext创建:
监听ServletContext销毁:
配置器监听器
<listener>
<listener-class>com.mzxy.listener.weblistener.MyServletContextListener</listener-class>
</listener>
ServletContextListener企业用途
1.加载框架的配置文件:
Spring框架提供了一个核心监听器,ContextLoadelistener
2.定时任务调度。
HttpSessionListener监听器的使用
HttpSessionListener监听器的作用
用来监听HttpSession对象的创建和销毁
HttpSession的创建和销毁
创建:服务器第一次调用getSession()方法的时候;
销毁:
非正常关闭服务器(正常关闭服务器session会被序列化)
Session过期(默认三十分钟)
手动调用session.invalidate()方法
HttpSessionListener监听器的方法
监听HttpSession创建:
监听HttpSession销毁:
关于监听器的一些小问题
- 如果访问一个HTML是否会创建session :不会
- 如果访问一个jsp是否会创建session :会(转换成servlet程序时默认调用了getSession方法了)
- 如果访问一个servlet是否会创建session :不会(默认没有调用getSession方法)
ServletRequestListener监听器的使用
ServletRequestListener监听器的作用
用于监听ServletRequest对象的创建和使用
ServletRequest对象的创建和销毁
创建:从客户端向服务器端发送一次请求,服务器就会创建request对象
销毁:服务器对这次请求做出响应之后,request对象就销毁了。
ServletRequestListener里面的方法
监听ServletRequest的创建:
监听ServletRequest的销毁:
疑问
- 访问HTML页面是否会创建请求对象 :会
- 访问jsp页面是否会创建请求对象 :会
- 访问servlet程序是否会创建请求对象 :会
第二类
监听三个域对象的属性变更的监听器
ServletContextAttributeListener
- 监听ServletContext对象中的属性变量(属性添加,移除,替换)的监听器
- 方法:
HttpSessionAttributeListener
- 监听HttpSeesion对象中的属性变量(属性添加,移除,替换)的监听器
- 方法
ServletRequestAttributeListener
- 监听ServletRequest对象中的属性变量(属性添加,移除,替换)的监听器
- 方法
(这三个监听器里面的方法都是一样,只不过的传入的参数不一样)
三个使用方法也是一致,编写类然后配置类。
第三类
监听HttpSession中Java类的状态改变的监听器
第三类监听器概述
保存在session域中的Java类可以有多种状态:绑定到session中,从session中解除绑定,随session对象持久化带一个存储设备中(转化),随session对象从一个存储设备中恢复(活化)。
Servlet对象中定义了两个特殊的监听器的接口来帮助Java类了解自己在session域中的状态。
HttpSessionBindingListener接口
HttpSessionActivationListener接口
实现这两个类的不需要在web.xml中进行配置
HttpSessionBindingListener
监听Java类在httpsession中的绑定和解除绑定的状态
方法:
代码演示:bean1.Java,demo3.jsp。
bean1.java
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
/**
* 监听HttpSession中Java类的绑定和解除绑定的监听器
* @author Warm
*
*/
public class Bean1 implements HttpSessionBindingListener{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
@Override
public void valueBound(HttpSessionBindingEvent arg0) {
System.out.println("Bean1与session绑定了");
}
@Override
public void valueUnbound(HttpSessionBindingEvent arg0) {
System.out.println("Bean1与session解除绑定了");
}
}
demo3.jsp:
<%@page import="com.itheima.listener.bean.Bean1"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Bean1 bean1 = new Bean1();
bean1.setName("张三");
//绑定必须是Java对象往里面放
session.setAttribute("bean1", bean1);
session.removeAttribute("bean1");
%>
</body>
</html>
HttpSessionActivationListener
代码:bean2.java+demo4.jsp+demo5.jsp
bean2.java
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
/**
* 监听HttpSession中对象的钝化活化监听器
* @author Warm
*
*/
public class Bean2 implements HttpSessionActivationListener,Serializable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void sessionDidActivate(HttpSessionEvent arg0) {
System.out.println("Bean2汇被session活化了");
}
@Override
public void sessionWillPassivate(HttpSessionEvent arg0) {
System.out.println("Bean2汇被session钝化了");
}
}
demo4.jsp:
<%@page import="com.itheima.listener.bean.Bean2"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Bean2 bean2 = new Bean2();
bean2.setName("张三");
session.setAttribute("bean2", bean2);
%>
</body>
</html>
demo5.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
${bean2.name}
</body>
</html>
通过配置来完成session的序列化和反序列化
Context标签可以配置在:
Tomcat/conf/context.xml : 所有tomcat下虚假主机和虚拟目录下的工程都会序列化session。
Tomcat/conf/Catalina/localhost/context.xml : localhost虚拟主机下的所有项目会被序列化session
工程/META-INF/context.xml :当前工程才会被序列化session
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="itheima"/>
</Manager>
</Context>
directory="itheima":这个文件夹会被系统创建
maxIdleSwap="1":一分钟不操作会被自动序列化
过滤器概述
1.什么是Filter
Filter称为过滤器,它是servlet技术中最实用的技术,web开发人员通过Filter技术,对web服务所管理的资源(jsp,servlet,静态图片或静态html文件)进行拦截,从而实现一些特殊的功能。
Filter就是过滤从客户端向服务器发送的请求
2.为什么学习过滤器
3.Filter入门
我们通过代码来展示:
FilterDemo1 .java
public class FilterDemo1 implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("FilterDemo1被创建了");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("FilterDemo1执行了");
//放行
chain.doFilter(request, response);
System.out.println("FilterDemo1执行结束了");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
System.out.println("FilterDemo1被销毁了");
}
}
fdemo1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>dmeo1页面</h1>
<%
System.out.println("demo1执行了");
%>
</body>
</html>
4.FilterChain对象的概述
什么是FilterChain
FilterChain过滤器链:在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为是一个过滤器链。
Web服务器根据filter在web.xml文件中的注册顺序(mapping的配置顺序)决定先调用那个filter。依次调用后面的过滤器,如果没有下一个过滤器。调用目标资源。
我们来演示一下:FilterChain的演示
首先我们去web.xml配置好
<!-- 过滤器 -->
<filter>
<filter-name>FilterDemo1</filter-name>
<filter-class>com.itheima.filter.demo1.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>FilterDemo2</filter-name>
<filter-class>com.itheima.filter.demo1.FilterDemo2</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
FilterDemo1.java+ FilterDemo2.java+ FilterDemo3.java+demo1.jsp
FilterDemo1.java:
public class FilterDemo1 implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("FilterDemo1被创建了");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("FilterDemo1执行了");
//放行
chain.doFilter(request, response);
System.out.println("FilterDemo1执行结束了");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
System.out.println("FilterDemo1被销毁了");
}
}
FilterDemo2.java:
public class FilterDemo2 implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("FilterDemo2执行了");
//放行
chain.doFilter(request, response);
System.out.println("FilterDemo2执行结束了");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
FilterDemo3.java:
public class FilterDemo3 implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("FilterDemo3执行了");
//放行
chain.doFilter(request, response);
System.out.println("FilterDemo3执行结束了");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
demo1.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>dmeo1页面</h1>
<%
System.out.println("demo1执行了");
%>
</body>
</html>
5.Filter生命周期
Filter的创建和销毁是由web服务器负责,web应用程序启动的时候,web服务器创建filter的实例对象,并调用其init方法进行初始化(filter对象只会创建一次,init方法也只会执行一次)
每次filter进行拦截的时候,都会执行doFilter方法
当服务器关闭的时候,应用从服务器中移出的时候,服务器会销毁Filter对象。
6.FilterConfig对象的概述
作用:用来获得Filter的相关配置的对象
方法:
看xml中的配置和FilterDemo4.java
public class FilterDemo4 implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//获得过滤器的名称
String filterName = filterConfig.getFilterName();
System.out.println("过滤器名称(filter-name):"+filterName);
//获得初始化参数
String username = filterConfig.getInitParameter("username");
String password = filterConfig.getInitParameter("password");
System.out.println("username:"+username);
System.out.println("password:"+password);
//获得所有参数信息
Enumeration<String> names = filterConfig.getInitParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = filterConfig.getInitParameter(name);
System.out.println(name+" "+value);
}
}
}
7.过滤器的相关配置
<url-pattern>配置
- 完全路径匹配 以/开始 比如/aaa
- 目录匹配 以/开始以*结束 比如/aaa/*
- 扩展名匹配 不能以/开始以*开始 比如*.jsp *.do
<servlet-name>配置
专门以servlet的配置名称拦截servlet
<dispatcher>配置
- 默认的情况下过滤器会拦截请求,如果进行转发(需要拦截这次转发)。
- Dispatcher的取值
REQUEST默认值,默认过滤器拦截的就是请求。
FORWARD转发。
INCLUDE页面包含的时候进行拦截
ERROR页面出现全局错误页面跳转的时候进行拦截