Java filter 和 interceptor

2022-05-25115

区别

1.使用范围和规范不同

  • filter是servlet规范规定的,只能用在web程序中.
  • 拦截器即可以用在web程序中, 也可以用于application, swing程序中, 是Spring容器内的, 是Spring框架支持的

2.触发时机不同

顺序: Filter-->Servlet-->Interceptor-->Controller

  • 过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前过滤器处理。
  • 拦截器是方法到达Controller层之前生效的

3.过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射,代理分静态代理和动态代理,动态代理是拦截器的简单实现。

何时使用拦截器?何时使用过滤器?

  • 如果是非spring项目,那么拦截器不能用,只能使用过滤器。
  • 如果是处理controller前后,既可以使用拦截器也可以使用过滤器。
  • 如果是处理dispaterServlet前后,只能使用过滤器。

4.在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

5.拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

6.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

7.拦截器可以获取IOC容器中的各个bean,而过滤器就不行,在拦截器里注入一个service,可以调用业务逻辑。

SpringBoot使用过滤器

两种方式:
1、使用spring boot提供的FilterRegistrationBean注册Filter
2、使用原生servlet注解定义Filter
两种方式的本质都是一样的,都是去FilterRegistrationBean注册自定义Filter

封装Filter

  1. package com.theeternity.common.baseFilter;
  2. import javax.servlet.Filter;
  3. /**
  4. * @program: ApiBoot
  5. * @description: 封装Filter
  6. * @author: TheEternity Zhang
  7. * @create: 2019-02-17 13:08
  8. */
  9. public interface MappingFilter extends Filter {
  10. String[] addUrlPatterns();
  11. int order();
  12. }

自定义Filter

  1. package com.theeternity.beans.filterConfig;
  2. import com.theeternity.common.baseFilter.MappingFilter;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import javax.servlet.*;
  7. import javax.servlet.FilterConfig;
  8. import java.io.IOException;
  9. /**
  10. * @program: ApiBoot
  11. * @description: 权限过滤器
  12. * @author: TheEternity Zhang
  13. * @create: 2019-02-17 13:14
  14. */
  15. public class AuthFilter implements MappingFilter {
  16. @Override
  17. public String[] addUrlPatterns() {
  18. return new String[]{"/*"};
  19. }
  20. @Override
  21. public int order() {
  22. return 0;
  23. }
  24. @Override
  25. public void init(FilterConfig filterConfig) throws ServletException {
  26. }
  27. @Override
  28. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  29. filterChain.doFilter(servletRequest,servletResponse);
  30. }
  31. @Override
  32. public void destroy() {
  33. }
  34. }

注册过滤器

  1. package com.theeternity.beans.filterConfig;
  2. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. /**
  6. * @program: ApiBoot
  7. * @description: 注册过滤器
  8. * @author: TheEternity Zhang
  9. * @create: 2019-02-17 13:10
  10. */
  11. @Configuration
  12. public class FilterConfig {
  13. @Bean
  14. public FilterRegistrationBean registFilter() {
  15. FilterRegistrationBean registration = new FilterRegistrationBean();
  16. AuthFilter authFilter=new AuthFilter();
  17. registration.setFilter(authFilter);
  18. registration.addUrlPatterns(authFilter.addUrlPatterns());
  19. registration.setOrder(authFilter.order());
  20. registration.setName("AuthFilter");
  21. return registration;
  22. }
  23. }

SpringBoot使用拦截器

封装Interceptor

  1. package com.theeternity.common.baseInterceptor;
  2. import org.springframework.web.servlet.HandlerInterceptor;
  3. /**
  4. * @program: ApiBoot
  5. * @description: 封装Interceptor
  6. * @author: TheEternity Zhang
  7. * @create: 2019-02-15 17:49
  8. */
  9. public interface MappingInterceptor extends HandlerInterceptor {
  10. String[] addPathPatterns();
  11. String[] excludePathPatterns();
  12. int order();
  13. }

自定义Interceptor

  1. package com.theeternity.beans.interceptorConfig;
  2. import com.theeternity.common.baseInterceptor.MappingInterceptor;
  3. import org.springframework.stereotype.Component;
  4. import org.springframework.web.servlet.ModelAndView;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. /**
  8. * @program: BoxApi
  9. * @description: 跨域拦截器
  10. * @author: tonyzhang
  11. * @create: 2018-12-21 14:44
  12. */
  13. @Component
  14. public class CrossOriginInterceptor implements MappingInterceptor {
  15. @Override
  16. public String[] addPathPatterns() {
  17. return new String[]{"/**"};
  18. }
  19. @Override
  20. public String[] excludePathPatterns() {
  21. return new String[0];
  22. }
  23. @Override
  24. public int order() {
  25. return 0;
  26. }
  27. @Override
  28. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  29. logger.info("允许的头信息"+request.getHeader("Origin"));
  30. response.setHeader("Access-Control-Allow-Origin", "*");
  31. response.setHeader("Access-Control-Allow-Methods", "*");
  32. response.setHeader("Access-Control-Max-Age", "3600");
  33. response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  34. //是否允许浏览器携带用户身份信息(cookie)
  35. response.setHeader("Access-Control-Allow-Credentials","true");
  36. return true;
  37. }
  38. @Override
  39. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  40. }
  41. @Override
  42. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) throws Exception {
  43. }
  44. }

注册Interceptor

  1. package com.theeternity.beans.interceptorConfig;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  6. /**
  7. * @program: ApiBoot
  8. * @description: 拦截器注册
  9. * @author: TheEternity Zhang
  10. * @create: 2019-02-15 17:55
  11. */
  12. @Configuration
  13. public class InterceptorConfig implements WebMvcConfigurer {
  14. @Autowired
  15. private CrossOriginInterceptor crossOriginInterceptor;
  16. @Override
  17. public void addInterceptors(InterceptorRegistry registry) {
  18. registry.addInterceptor(crossOriginInterceptor).addPathPatterns(crossOriginInterceptor.addPathPatterns());
  19. }
  20. }