SpringBoot之过滤器和拦截器

一、浅析过滤器和拦截器

1、过滤器:

它依赖于servlet容器。它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等。

2、拦截器:

它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。拦截器可以对静态资源的请求进行拦截处理。

3、区别:

  1)Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。

  2)Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理的方式来执行。

  3)Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

 

二、建立过滤器

1、创建过滤器TestFilter

@Order(1)
@WebFilter(filterName = "testFilter", urlPatterns = "/*" , initParams = {
@WebInitParam(name = "URL", value = "http://localhost:8080")})
public class TestFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(TestFilter.class);

/**
* init : filter对象只会创建一次,init方法也只会执行一次。
* doFilter : 主要的业务代码编写方法,可以多次重复调用
* destroy : 在销毁Filter时自动调用(程序关闭或者主动销毁Filter)
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
logger.info("================Remote Host:" + servletRequest.getRemoteHost());
logger.info("================Remote Address:" + servletRequest.getRemoteAddr());
filterChain.doFilter(servletRequest, servletResponse);
}

@Override
public void destroy() {
}
}

注:
@Order(1):表示过滤器的顺序,假设我们有多个过滤器,你如何确定过滤器的执行顺序?这个注解就是规定过滤器的顺序。
@WebFilter:表示这个class是过滤器。里面的参数:filterName 为过滤器名字,urlPatterns 为过滤器的范围,initParams 为过滤器初始化参数。

2、在启动类上添加注解@ServletComponentScan
SpringBoot之过滤器和拦截器

 补:可以直接在过滤器类上添加注解@Component,无须再在启动类上添加注解,spring也会自动加载


三、建立拦截器

1、创建自定义拦截器

要使用拦截器,需要创建支持它的@Component类,它应该实现HandlerInterceptor接口。 

 

/**
* preHandle()方法 - 用于在将请求发送到控制器之前执行操作。此方法应返回true,以将响应返回给客户端。
* postHandle()方法 - 用于在将响应发送到客户端之前执行操作。
* afterCompletion()方法 - 用于在完成请求和响应后执行操作
*/
@Component
public class LoginHandlerInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(HandlerInterceptor.class);
@Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.info("Pre Handle method is Calling");
return true;
}
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.info("Post Handle method is Calling");

}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception exception) throws Exception {
logger.info("Request and Response is completed");
}

}

2、使用WebMvcConfigurerAdapterInterceptorRegistry注册此Interceptor
@Configuration
public class LoginHandlerInterceptorAppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册LoginHandlerInterceptor拦截器
InterceptorRegistration registration = registry.addInterceptor(new LoginHandlerInterceptor());
//所有路径都被拦截
registration.addPathPatterns("/**");
}
}

 四、测试

访问接口控制台打印:

SpringBoot之过滤器和拦截器

 

上一篇:直播系统平台搭建,管理下划线颜色、高度设置标题是否居中


下一篇:springboot类型转换器