过滤器和拦截器

过滤器 filter

springboot使用filter

1、实现Filter接口

@WebFilter(urlPatterns = "/*")//匹配的url路径
public class AppFilter implements Filter {

    /**
     * 通过WebFilter配置拦截器,可以注入成员
     */
    @Autowired
    private TestComponent testComponent;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("拦截器init");
    }

    /**
     * 拦截请求
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        String method = testComponent.method();
        System.out.println("过滤器");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    /**
     * 程序终止的时候调用
     */
    @Override
    public void destroy() {
        System.out.println("拦截器destroy");
    }
}

2、在主类上开启servlet组件的扫描(包括servlet,filter,listener)

@SpringBootApplication
@ServletComponentScan(basePackages = {"com.interceptortest.demo.filter"})//开启扫描filter
public class DemoApplication {

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

}

拦截器 Intercepter

springboot中使用Intercepter

url路径的方式

1、继承HandlerInterceptorAdapter类,实现preHandle方法


@Component
public class AppIntercepter extends HandlerInterceptorAdapter {

    @Autowired
    private TestComponent testComponent;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器生效\t通过路径拦截");
        return true;
    }
}

2、实现WebMvcConfigurer接口,重写addInterceptors方法

@Configuration
public class IntercepterConfig implements WebMvcConfigurer {

    @Autowired
    private AppIntercepter appIntercepter;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //采用注入的方式配置,则Intercepter中可以自动注入成员变量
        registry.addInterceptor(appIntercepter).addPathPatterns("/app/**");
        //如果是采用new的方式注入,则Intercepter中不能自动注入成员变量,需要手动获取
        registry.addInterceptor(new TestIntercepter()).addPathPatterns("/test/**");
    }
}

使用注解方式

其实使用注解的方式,原理是将拦截器的作用的url设置为"/*",然后通过判断方法上是否有注解来进行处理


public class TestIntercepter extends HandlerInterceptorAdapter {

    @Autowired
    private TestComponent testComponent;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //registry.addInterceptor(new TestIntercepter()).addPathPatterns("/test/**");
        //如果是采用new的方式注入,则Autowired的字段不会生效,需要重新在上下文中获取
        if (testComponent == null) {
            WebApplicationContext requiredWebApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
            testComponent = (TestComponent) requiredWebApplicationContext.getBean("testComponent");

        }

        HandlerMethod method = (HandlerMethod) handler;
        Anno loginRequired = method.getMethodAnnotation(Anno.class);
        if (Objects.isNull(loginRequired)) {
            System.out.println("无需拦截");
            return true;
        } else {
            System.out.println("通过注解拦截");
            return false;
        }
    }
}

注意

registry.addInterceptor方法中,最好不要new一个拦截器,因为这样通过spring注入的成员会丢失。
解决方法
通过上下文重新获取

        if (testComponent == null) {
            WebApplicationContext requiredWebApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
            testComponent = (TestComponent) requiredWebApplicationContext.getBean("testComponent");
        }

拦截器Intercepter和过滤器filter区别

1、filter在intercepter之前执行
2、intercepter可以通过handler获取更多的信息,包括方法名等(但是获取不到方法参数),但filter只有http相关信息

git

https://github.com/lexiaoyao1995/jwt_interceper_filter

posted @ 2020-09-04 17:08  刃牙  阅读(198)  评论(0编辑  收藏  举报