java之 Filter&Listener
0x01、Filter
什么是filter ?
Filter:一个实现了特殊接口(Filter)的Java类. 实现对请求资源(jsp,servlet,html,)的过滤的功能.
过滤器是一个运行在服务器的程序, 优先于请求资源(Servlet或者jsp,html)之前执行. 过滤器是javaweb技术中最为实用的技术之一.
对目标资源(Servlet,jsp)进行过滤.
应用场景:登录权限检查,解决网站乱码,过滤敏感字符 ...
1、配置文件方式
<filter>
<!--filter-name:filter名字 随便取的(一般用类名, 不要重复)-->
<filter-name>FilterDemo01</filter-name>
<!--filter-class:filier类的全限定名-->
<filter-class>com.itheima.day01.FilterDemo01</filter-class>
</filter>
<!--配置Filter拦截映射的路径-->
<filter-mapping>
<!--filter-name:必须和filter里面的filter-name一致-->
<filter-name>FilterDemo01</filter-name>
<!--url-pattern:匹配的路径-->
<url-pattern>/demo01</url-pattern>
</filter-mapping>
2、注解方式
- 创建一个类实现Filter接口
- 直接在这个类上面添加注解进行配置
3、Filter生命周期
init(FilterConfig):初始化
doFilter(ServletReqeust req,ServletResponse resp,FilterChain chain):执行过滤的方法
destroy():销毁
- 服务器启动的时候, 会调用init()方法进行初始化【调用一次】
- 任何一次请求都会调用doFilter()方法进行过滤【路径相匹配】
- 服务器正常关闭或者项目从服务器移除, 调用destory()方法进行销毁【调用一次】
注意: 默认情况下,Servlet是来了第一次请求的时候 调用init()方法进行初始化.我们可以在Servlet里面设置启动项.
- 完全路径匹配
/demo01
- 目录匹配
/* 匹配所有的资源 /aa/* 匹配以/aa开头的资源
- 扩展名匹配
*.jsp 匹配上了所有的jsp *.html 匹配上了所有的html
- 缺省匹配 / 匹配除了jsp以为的所有的资源
/ 除了jsp 其它的都匹配
/* 匹配所有
4、拦截方式
-
通过dispatcherTypes配置拦截方式
-
DispatcherType.FORWARD: 【只】过滤转发
-
DispatcherType.REQUEST: 除了转发以为其它的都过滤(1.浏览器的直接请求 2.重定向)【默认值】
-
-
拦截方式的这个值,我们可以配置多个
@WebFilter(value = {"/demo06"},dispatcherTypes={DispatcherType.FORWARD,DispatcherType.REQUEST})
一般情况下, 转发我们不会过滤的. 转发属于服务器内部的行为. 直接使用默认值的情况偏多
5、过滤链
过滤器链执行顺序
- 配置文件: 谁先配置
filter-mapping
谁先执行 - 注解方式: 按照Filter的首字母顺序 eg: AFilter BFilter A在B的前面, AFilter先执行
0x02、Listener
什么是Listener
-
监听器就是一个Java类,用来监听其他的JavaBean对象的变化
-
在javaweb中监听器就是监听三个域对象的状态的。request,session,servletContext(application)
作用:
-
主要在Swing编程
-
在Android/ios大量应用
-
JS里面的事件
监听器术语:
eg: 一个狗仔拍明星出轨
事件源 :被监听的对象.(目标对象) 明星
监听器对象:监听的对象. 狗仔
事件:事件源行为的称呼. 出轨
注册(绑定):将"监听器"对象注册给"事件源". 狗仔需要和明星绑定(跟踪, 蹲点...)
事件对象:在"监听器对象"中获得"事件源" 狗仔的镜头里面获得明星出轨证据
listener 监听器实现:
首先我们需要实现ServletContextListener
的接口,该接口并没有一个定义好的实现类,需要自己进行定义。
ServletContextListener方法:
void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法
void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法
代码:
- 配置java代码
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* 一、写一个类实现ServletContextListener接口,并重写方法
* 方法1: contextInitialized()会在ServletContext对象创建的时候执行,也就是在服务器启动的时候
* 方法2: contextDestroyed()会在ServletContext对象销毁的时候执行,也就是在服务器关闭的时候
*
* 二、在web.xml中配置监听器
*/
public class MyContextListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了服务器的启动....创建spring的核心容器");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听到了服务器的关闭....销毁spring的核心容器");
}
}
- 配置(web.xml)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<listener>
<listener-class>com.itheima.listener.MyContextListener</listener-class>
</listener>
</web-app>
应用: Spring框架里面, 服务器启动时候, 就加载Spring框架 初始化