blog
原创

JavaWeb学习笔记——Filter & Listener

@[TOC]

Filter 过滤器

当访问服务器资源的时候,过滤器可以将请求拦截下来,并完成一些特殊的功能,如:登录验证,统一编码处理,敏感字符过滤等

基本使用方法

  1. 定义一个类来实现Filter接口
public class FilterDemo implements Filter

注:实现的Filter接口应为javax.servlet下的Filter

  1. 复写方法
public class FilterDemo implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("FilterDemo1");
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}
  1. 配置拦截路径

使用WebFilter注解或web.xml来配置

@WebFilter("/*") // 访问所有资源之前都会执行过滤器
public class FilterDemo implements Filter{
    ...
}

Filter细节

Filter执行过程

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter Go.....");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("Filter Come.....");
    }

在客户请求资源时,会先经过过滤器,过滤器放行后才可以获取资源,当获取资源之后同样要再一次经过过滤器

以放行方法doFilter()为界,方法之上的语句都是对request对象的请求消息增强,方法之下的语句都是对response对象的响应消息增强

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 对request对象的请求消息增强
        System.out.println("Filter Go.....");

        // 放行
        filterChain.doFilter(servletRequest, servletResponse);

        // 对response对象的响应消息增强
        System.out.println("Filter Come.....");
    }

显示结果为

Filter Go.....
请求资源的输出内容.....
Filter Come.....

Filter的生命周期方法

在服务器启动之后,会创建Filter对象,并调用init()方法,只执行一次,用于加载资源

每一次请求被拦截资源时,会执行doFilter()方法,可以执行多次

在服务器关闭后,会销毁Filter对象,若服务器正常关闭,则会调用destory()方法,只执行一次,用于释放资源

@WebFilter("/*")
public class FilterDemo implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init....");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("doFilter....");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("destory....");
    }
}

启动服务器时控制台输出

init....
doFilter....
请求资源的输出内容....

刷新一次后

init....
doFilter....
请求资源的输出内容....
doFilter....
请求资源的输出内容....

关闭服务器

init....
doFilter....
请求资源的输出内容....
doFilter....
请求资源的输出内容....
destory....

Filter的配置

拦截路径
描述
拦截具体资源路径 /index.jsp 只有访问指定路径的资源才会执行过滤器
拦截目录 /jsp/* 访问指定目录下的所有资源都会执行过滤器
拦截后缀名 *.jsp 访问所有指定后缀的资源都会执行过滤器
拦截所有资源 /* 访问所有资源时都会执行过滤器
拦截方式

给过滤器指定资源被访问的方式,以拦截该访问方式的请求

注解配置

设置dispatcherTypes属性

  1. REQUEST:默认值,浏览器直接请求资源
  2. FORWARD:转发访问资源
  3. INCLUDE:包含访问资源
  4. ERROR:错误跳转资源
  5. ASYNC:异步访问资源
web.xml配置

设置<dispathcer></dispatcher>标签

过滤器链

如果存在两个过滤器,分别为F1,F2则过滤器的执行顺序为

F1 -> F2 -> 资源执行 -> F2 -> F1

示例

F1

@WebFilter("/*")
public class F1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("F1 Go...");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("F1 Come...");
    }

    @Override
    public void destroy() {

    }
}

F2

@WebFilter("/*")
public class F2 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("F2 Go...");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("F2 Come...");
    }

    @Override
    public void destroy() {

    }
}

显示结果为

F1 Go...
F2 Go...
访问资源输出...
F2 Come...
F1 Come...
过滤器执行先后顺序问题
注解配置

按照类名进行字符串比较,值较小的先执行

web.xml配置

按照<filter-mapping>标签的定义顺序执行

Listener 监听器

事件监听机制

  • 事件:某些操作

  • 事件源:某些组件,即事件发生的位置

  • 监听器:一个对象

  • 注册监听:将事件,事件源和监听器绑定在一起,当事件源上发生某个事件,则触发监听器

ServletContextListener接口

需要实现的方法

① void contextInitialized(ServletContextEvent servletContextEvent)

ServletContext对象被创建之后调用该方法,可用于加载资源文件

② void contextDestroyed(ServletContextEvent servletContextEvent)

ServletContext对象被销毁之前调用该方法

使用步骤

  1. 定义一个类来实现ServletContextListener接口
  2. 实现接口方法
public class ListenerDemo implements ServletContextListener {

    // 监听ServletContext对象的创建,服务器启动后自动调用
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("创建ServletContext...");
    }

    // 监听ServletContext对象的销毁,服务器正常关闭之前调用该方法
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("销毁ServletContext...");
    }
}
  1. 配置Listener

web.xml中添加<listener>标签

<listener>
        <listener-class>Listener.ListenerDemo</listener-class>
    	<!-- listener-class 内填写Listener类的全类名 -->
</listener>

也可以使用@WebListener注解来配置Listener

Java Web
  • 作者:Melonico
  • 发表时间:2021-03-15 17:54
  • 更新时间:2021-03-15 17:54

评论

暂无评论,快来发表第一个评论吧!
留言
TOP