Spring Boot 入门之路(4)--- Filter,Listener,HandlerInterceptor的使用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Geffin/article/details/99709970

上文我们已经介绍过 Servlet 的使用,实际上过滤器(Filter)和 监听器(Listener)的使用与 Servlet 大同小异,不信?且听我娓娓道来。

1 过滤器(Filter)的实现

@WebFilter(filterName="myFirstFilter",urlPatterns="/*")
public class myFirstFilter implements Filter {
	
	@Override
    public void init(FilterConfig config){
        System.out.println("init()");
    }
	
	@Override
    public void destroy() {
        System.out.println("destroy()");
    }

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		System.out.println("doFilter()");
		arg2.doFilter(arg0, arg1);
	}

}

@WebFilter 将一个实现了 javax.servlet.Filter 接口的类定义为过滤器,其中属性 filterName 是可选的,用于声明过滤器的名称,而属性 urlPatterns 是必选的,指定要过滤的URL模式。

当然 @ServletComponentScan 注解是必须加到 TestApplication.java 上的:

@ServletComponentScan
@SpringBootApplication
public class TestApplication {

	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);
	}

}

随意打开一个页面,可观察到
在这里插入图片描述
过滤器的确起到作用。

2 监听器(Listener)的实现

其中 TestApplication.java 与上面相同,我们的监听器举例就以 ServletContextListener 为例

@WebListener
public class MyFirstListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContex begin()");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContex destroy()");
    }

}

@WebListener 表示注册一个监听器。我们直接运行 TestApplication.java ,可以观察到
在这里插入图片描述
证明我们的监听器发挥到作用。

3 拦截器(HandlerInterceptor)的实现

在 Java Web 工程中,除了使用过滤器来过滤 web 请求外,我们还可以使用拦截器。他们两个的区别是,过滤器是 Servlet 的API,而拦截器是由 Spring 提供的。

其实,拦截器的功能与过滤器区别不大,但它的控制能力更强。注意,我们不能通过拦截器修改request 的内容,但我们可以暂停 request 的执行。

实现拦截器只需要三步:

  1. 创建实现了 HandlerInterceptor 接口的拦截器类
  2. 创建一个类实现 WebMvcConfigurer 接口
  3. 实例化自定义的拦截器,然后将对象添加到拦截器链中

下面我们进行代码的模拟

//拦截器1
public class MyFirstInterceptor implements HandlerInterceptor{

	// 只有返回true才会继续向下执行,返回false取消当前请求
	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("在请求处理之前进行调用 MyFirstInterceptor");

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("请求处理之后,视图被渲染之前进行调用 MyFirstInterceptor");
    }

    //主要是用于进行资源清理工作
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("请求结束之后,渲染视图之后进行调用 MyFirstInterceptor");
    }
}

//拦截器2
public class MySecondInterceptor implements HandlerInterceptor{

	// 只有返回true才会继续向下执行,返回false取消当前请求
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
          throws Exception {
      System.out.println("在请求处理之前进行调用 MySecondInterceptor");

      return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
          ModelAndView modelAndView) throws Exception {
      System.out.println("请求处理之后,视图被渲染之前进行调用 MySecondInterceptor");
	}

	//主要是用于进行资源清理工作
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
          throws Exception {
      System.out.println("请求结束之后,渲染视图之后进行调用 MySecondInterceptor");
	}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //多个拦截器组成一个拦截器链,addPathPatterns 用于添加拦截规则,excludePathPatterns 用于排除拦截
        registry.addInterceptor(new MyFirstInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(new MySecondInterceptor()).addPathPatterns("/**");
    }
}

在浏览器输入 http://localhost:8080/hello , 控制台输出如下:
在这里插入图片描述
注意,拦截器与过滤器还有一个区别,只有经过 DispatcherServlet 的请求,才会走拦截器链,自定义的 Servlet 请求是不会被拦截的。而只要符合过滤器的过滤规则的 Servlet ,过滤器是来者不拒的。

参考:Spring Boot 过滤器、监听器
Spring Boot 拦截器

猜你喜欢

转载自blog.csdn.net/Geffin/article/details/99709970