JavaEE中的过滤器和拦截器

前言

对于Interceptor和Filter,在很多时候都可以混淆使用,都是可以拦截用户请求,然后做一些事情。为了不混淆两者关系,在此整理了关于拦截器和过滤器的相关知识和区别。

过滤器Filter

Filter说明

过滤器是处于客户端和服务器资源文件之间的一道过滤网,在访问资源之前,通过一系列的拦截器,即构成的拦截器链FilterChain,对响应进行过滤拦截和修改。

Filter是JavaEE规范中的,是Servlet最实用的技术,通过Filter,就可以对Web服务器管理的所有Web资源如JSP、Servlet等等进行拦截,

具体的应用场景应该有URL级别的权限访问控制,过滤敏感词汇,压缩响应信息等等。

主要用作对用户请求进行预处理,也可以对response进行后处理。Filter的处理流程:Filter对用户请求进行预处理,接着讲请求交给Servlet进行处理并生成响应,最后Filter对服务器响应进行后处理。自定义的Filter还需要实现Filter接口。

TIM截图20180823151130-2018823

Filter工作原理

可以从上图看到,Filter接口中有三个方法,分别为init、doFilter、destroy,分别对应着初始化,过滤、销毁。

当我们写好了Filter的时候,还需要配置该Filter是要对哪些资源进行过滤。

当每次用户请求到达服务器后,在未到达具体请求的资源之前,Web服务器都会先调用Filter的doFilter方法进行处理,然后该方法传入的参数有一个FilterChain,如果处理完成放行会继续执行该FilterChain的doFilter方法,如果不放行就不继续执行该FilterChain的doFilter方法。

Filter的编写流程

1、编写一个类实现Filter接口,并实现其带的init、doFilter、destroy方法。

2、在doFilter方法中编写具体的逻辑,根据逻辑需要选择放行FilterChain。

3、在web.xml文件中配置过滤器(注册和映射),需要使用标签以及

Filter的生命周期

Filter创建

Filter的创建和销毁由Web容器负责,在Web应用启动的时候,Web服务器将创建Filter的实例对象,并调用init方法完成对象的初始化。

Filter对象只会创建一次,init方法也只会执行一次。通过init方法的参数FilterConfig可以获得代表当前Filter的Config。

而这些参数,一般来源于web.xml中的init-param。在web.xml文件中配置的时候可以通过来为Filter配置一些启动参数。

FilterConfig常用方法示例:

1
2
3
4
5
6
7
8
 @Override
public void init(FilterConfig filterConfig) throws ServletException {
String filterName = filterConfig.getFilterName();//获取Filter的Name
String initParam = filterConfig.getInitParameter("initParam");//获取名称为initParam的初始参数的值
Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();//获取所有的初始化参数的美聚集和while (initParameterNames.hasMoreElements()) {
System.out.println(initParameterNames.nextElement());
}
}

Filter的销毁

在Web容器关闭之前,会调用Filter的destroy方法来销毁Filter,在此方法中,可以释放掉过滤器使用的资源。

拦截器Interceptor

拦截器在开源框架中很常见,依赖的技术就是JavaJDK的动态代理,当然还有基于CGLIB的动态代理,关于这两种的代理区别,JDK的动态代理是需要用到接口Interface的,没有接口就不能实现动态代理,而CGLIB就可以不需要接口。

在这里呢,说下Spring中的Interceptor,依赖于Web框架,也是一种AOP的运用。由于拦截器是Web框架的调用,因此可以使用Spring的DI依赖注入,同时一个Controller可以在一个Controller的生命周期中多次被调用。

Interceptor只能拦截Controller,对于一些静态资源则不能拦截处理。

实现一个自定义的Interceptor

1、需要实现HandlerInterceptor接口,并实现以下的三个方法,关于多个Interceptor执行,在preHandler执行完毕后的返回值会影响接下来执行的Interceptor,这里不做说明。

2、在Spring的配置文件中配置Interceptor。注意拦截器的执行顺序和配置文件的顺序有关。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class MyInterceptor implements HandlerInterceptor {
/**
* 在Dispatcher之前执行
*
* @param request
* @param response
* @param handler
* @return true:表示继续执行拦截器链,如果返回为false,就不会继续执行Controller
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}

/**
* 在Controller执行完毕之后,在视图解析器之前被执行
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}

/**
* 在视图解析器执行完毕后,在返回给客户端之前执行
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}
-------------The End-------------

本文标题:JavaEE中的过滤器和拦截器

文章作者:Dimple

发布时间:2018年08月23日 - 14:08

最后更新:2018年09月28日 - 17:09

原始链接:http://www.bianxiaofeng.com/2018/08/23/2018-8-23-14-51-13/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

na,给我一个棒棒糖!
0%