通过过滤器(Filter),可以实现用户访问某个资源前,对访问的请求和响应进行过滤。
一:原理:在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要的数据。比如在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括低俗文字,危险字段等。
二:过滤器调用顺序:
Filter——>Interceptor——>Aspect——>Controller
当Controller抛出的异常处理顺序则是相反的,因此我们总是定义一个注解@ControllerAdvice去统一处理控制器抛出的异常,如果一旦异常被@ControllerAdvice处理了,则调用拦截器的afterCompletion方法的参数Exception ex就为空了。
注意:启动类加@ServletComponentScan(“过滤器路径”)
不论是注解配置还是Java配置,都需要在启动类上加上@ServletComponentScan(“过滤器路径”)注解,过滤路径可以不写。注解注册和Java配置类注册,它们的自定义过滤器类都是一样的,只不过注册过程一个是通过@WebFilter注解,一个是通过Java配置类注册Bean。
方法一:过滤器(注解注册过滤器)
自定义过滤器
/**
* 自定义注解过滤器实现
* Filter的包是javax.servlet.Filter的
* filterName:过滤器名称,需要唯一,不能重复
* urlPatterns:要拦截的url资源路径,注意:通配符是一个星号(*)
*/
@Order(2)//排序注解,执行顺序
@WebFilter(filterName = "filterAnnotation",urlPatterns = {"/study/interfaces/v1/user"})
public class filterAnnotation implements Filter {
//初始化操作,只会执行一次
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filterAnnotation--初始化Filter");
}
//进入到过滤资源之前和之后做的事情
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filterAnnotation--进入Target Resource之前做的事情");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("filterAnnotation--处理返回的Response");
}
//销毁,只会在项目停止或者重新部署的时候才会执行
@Override
public void destroy() {
System.out.println("filterAnnotation--销毁Filter");
}
}
方法二:过滤器(配置类注册过滤器)
自定义过滤器
/**
* 自定义java过滤器实现,通过配置类注册
*/
public class FilterJava implements Filter {
//初始化操作,只会执行一次
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filterAnnotation--初始化Filter");
}
//进入到过滤资源之前和之后做的事情
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filterAnnotation--进入Target Resource之前做的事情");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("filterAnnotation--处理返回的Response");
}
//销毁,只会在项目停止或者重新部署的时候才会执行
@Override
public void destroy() {
System.out.println("filterAnnotation--销毁Filter");
}
}
过滤器配置类
/**
* 作用相当于@WebFilter这个注解
* 过滤器配置类,进过滤器配置到bean中
* Filter的包是javax.servlet.Filter的
*/
@Configuration//这个注解的目的是被IOC容器获取到
public class FilterConfig {
@Bean
public FilterRegistrationBean filter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new FilterJava());//注册自定义过滤器类
filterRegistrationBean.addUrlPatterns("/study/interfaces/v1/user");//过滤资源的路径,或者静态资源,注意:通配符是一个星号(*)
filterRegistrationBean.setName("filterJava");//要拦截的url资源路径,注意:通配符是一个星号(*)
filterRegistrationBean.setOrder(1);//排序
return filterRegistrationBean;
}
}