Servlet:监听器和过滤器

文章目录

1. 监听器Listener

概念:web的三大组件之一。

  • 事件监听机制的三个部分:
    事件 :一件事情
    事件源 :事件发生的地方
    监听器 :一个对象
    * 注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码
    Servlet:监听器和过滤器
    6个主要监听器:
    ServletRequestListenerServletContextListenerHttpSessionListener接口是用于监听对象的创建与销毁信息;ServletContextAttributeListener,HttpSessionAttributeListenerServletRequestAttributeListener,这三个接口则是定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。

例举.ServletContext对象监听器

package listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.FileInputStream;
/**
 * Listener入门:
 * 1.ServletContext对象监听器
 * */
//@WebListener()
public class ListenerDemo1 implements ServletContextListener {
    /**
     * 监听ServletContext对象创建的,ServletContext对象服务器启动后自动创建的。
     * 在服务器启动后自动调用
     * */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //加载资源文件
        //1.获取ServletContext对象
        ServletContext servletContext = sce.getServletContext();

        //2.加载资源文件
        String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");

        //3.获取真实路径
        String realPath = servletContext.getRealPath(contextConfigLocation);

        //4.加载进内存
        try{
            FileInputStream fis = new FileInputStream(realPath);
            System.out.println(fis);//java.io.FileInputStream@4a3ee766
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("ServletContext对象被创建了。。。");//ServletContext对象被创建了。。。
    }

    /**
     * 在服务器关闭后,ServletContext对象被销毁,当服务器正常关闭后该方法被调用
     * */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext对象被销毁了。。。");//ServletContext对象被销毁了。。。
    }
}
<!-- 指定初始化参数 -->
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
   </context-param>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<bean></bean>

2. 过滤器filter

web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
(1)@WebFilter("/*")//访问所有资源之前,都会执行该过滤器
//放行代码
filterChain.doFilter(servletRequest,servletResponse);

package filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
* 过滤器快速入门程序
* */
@WebFilter("/*")//访问所有资源之前,都会执行过滤器
public class FilterDemo1 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("Filter的doFilter同Servlet的service:过滤器被执行了");
       //放行代码
       filterChain.doFilter(servletRequest,servletResponse);
   }
   @Override
   public void destroy() {
   }
}

(2)过滤器执行流程和过滤器的生命周期:

  • 1.过滤器执行流程
    (1). 执行过滤器
    (2). 执行放行后的资源
    (3). 回来执行过滤器放行代码下边的代码
  • 2.过滤器生命周期方法
    (1). init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
    (2). doFilter:每一次请求被拦截资源时,会执行。执行多次
    (3). destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
package filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class FilterDemo2 implements Filter {
    //在服务器启动后,会创建Filter对象,然后调用init方法,只执行一次,用于加载资源
    public void init(FilterConfig config) throws ServletException {
        System.out.println("init....");
    }
    //每一次请求被拦截资源时,会执行,执行多次
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain) throws ServletException, IOException {
        //对request对象请求消息增强
        System.out.println("FilterDemo2执行了。。。");
        //放行
        filterchain.doFilter(request, response);
        //对response对象响应消息增强:回来执行过滤器放行代码下边的代码
        System.out.println("FilterDemo2回来了");
    }
    //在服务器正常关闭后,Filter对象被销毁,会执行destroy方法,只执行一次,用于释放资源
    public void destroy() {
        System.out.println("destroy......");
    }
}

(3)注解的各种形式
@WebFilter("/index.jsp") //1. 具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
@WebFilter("/user/*") //2. 拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行
@WebFilter("*.jsp") //3. 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行

@WebFilter("/*") //4.拦截所有

package filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class FilterDemo3 implements Filter {
    public void init(FilterConfig config) throws ServletException {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain) throws ServletException, IOException {
        System.out.println("FilterDemo4开始。。。");
        //放行
        filterchain.doFilter(request, response);
    }
    public void destroy() {
    }
}

(4)注解配置

注解配置:

  1. REQUEST:默认值。浏览器直接请求资源
  2. FORWARD:转发访问资源
  3. INCLUDE:包含访问资源
  4. ERROR:错误跳转资源
  5. ASYNC:异步访问资源
  • 浏览器直接请求index.jsp资源时,该过滤器会被执行
    @WebFilter(value="/index.jsp",dispatcherTypes = DispatcherType.REQUEST)
  • 只有转发访问index.jsp时,该过滤器才会被执行
    @WebFilter(value="/index.jsp",dispatcherTypes = DispatcherType.FORWARD)
  • 浏览器直接请求index.jsp或者转发访问index.jsp。该过滤器才会被执行
    @WebFilter(value="/index.jsp",dispatcherTypes ={ DispatcherType.FORWARD,DispatcherType.REQUEST})
package filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(value="/index.jsp",dispatcherTypes ={ DispatcherType.FORWARD,DispatcherType.REQUEST})
public class FilterDemo4 implements Filter {
    public void init(FilterConfig config) throws ServletException {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain) throws ServletException, IOException {
        System.out.println("filterDemo4....");
        filterchain.doFilter(request, response);
    }
    public void destroy() {
    }
}

(5)过滤器执行先后顺序
执行顺序:如果有两个过滤器:过滤器1和过滤器2

  1. 过滤器1
  2. 过滤器2
  3. 资源执行
  4. 过滤器2
  5. 过滤器1

过滤器先后顺序问题:
1.注解配置:按照类名的字符串比较规则比较,值小的先执行
如: AFilter 和 BFilter,AFilter就先执行了。
2. web.xml配置: 谁定义在上边,谁先执行

FilterDemo5

package filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
 /* 结果:
 * FilterDemo5执行了。。。
 * FilterDemo6执行了。。。
 * index执行。。。
 * FilterDemo6回来了。。。
 * FilterDemo5回来了。。。
 * */
@WebFilter("/*")
public class FilterDemo5 implements Filter {
    public void init(FilterConfig config) throws ServletException {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain) throws ServletException, IOException {
        System.out.println("FilterDemo5执行了。。。");
        filterchain.doFilter(request, response);
        System.out.println("FilterDemo5回来了。。。");
    }
    public void destroy() {
    }
}

FilterDemo6

package filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//@WebFilter("/*")
public class FilterDemo6 implements Filter {
    public void init(FilterConfig config) throws ServletException {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain) throws ServletException, IOException {
        System.out.println("FilterDemo6执行了。。。");
        filterchain.doFilter(request, response);
        System.out.println("FilterDemo6回来了。。。");
    }
    public void destroy() {
    }
}

Servlet:监听器和过滤器Servlet:监听器和过滤器 灰色头像JH 发布了64 篇原创文章 · 获赞 10 · 访问量 3259 私信 关注
上一篇:DispatherServlet执行流程


下一篇:Sping 里面的适配器模式的实现