过滤器和拦截器

过滤器 filter

springboot使用filter

1、实现Filter接口

@WebFilter(urlPatterns = "/*")//匹配的url路径
public class AppFilter implements Filter {
<span class="hljs-comment">/**
 * 通过WebFilter配置拦截器,可以注入成员
 */</span>
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> TestComponent testComponent;

<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">init</span><span class="hljs-params">(FilterConfig filterConfig)</span> <span class="hljs-keyword">throws</span> ServletException </span>{
    System.out.println(<span class="hljs-string">"拦截器init"</span>);
}

<span class="hljs-comment">/**
 * 拦截请求
 *
 * <span class="hljs-doctag">@param</span> servletRequest
 * <span class="hljs-doctag">@param</span> servletResponse
 * <span class="hljs-doctag">@param</span> filterChain
 * <span class="hljs-doctag">@throws</span> IOException
 * <span class="hljs-doctag">@throws</span> ServletException
 */</span>
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doFilter</span><span class="hljs-params">(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)</span> <span class="hljs-keyword">throws</span> IOException, ServletException </span>{
    String method = testComponent.method();
    System.out.println(<span class="hljs-string">"过滤器"</span>);
    filterChain.doFilter(servletRequest, servletResponse);
}

<span class="hljs-comment">/**
 * 程序终止的时候调用
 */</span>
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">destroy</span><span class="hljs-params">()</span> </span>{
    System.out.println(<span class="hljs-string">"拦截器destroy"</span>);
}

}

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

@SpringBootApplication
@ServletComponentScan(basePackages = {"com.interceptortest.demo.filter"})//开启扫描filter
public class DemoApplication {
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
    SpringApplication.run(DemoApplication.class, args);
}

}

拦截器 Intercepter

springboot中使用Intercepter

url路径的方式

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


@Component
public class AppIntercepter extends HandlerInterceptorAdapter {
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> TestComponent testComponent;

<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">preHandle</span><span class="hljs-params">(HttpServletRequest request, HttpServletResponse response, Object handler)</span> <span class="hljs-keyword">throws</span> Exception </span>{
    System.out.println(<span class="hljs-string">"拦截器生效	通过路径拦截"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}

}

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

@Configuration
public class IntercepterConfig implements WebMvcConfigurer {
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> AppIntercepter appIntercepter;

<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">addInterceptors</span><span class="hljs-params">(InterceptorRegistry registry)</span> </span>{
    <span class="hljs-comment">//采用注入的方式配置,则Intercepter中可以自动注入成员变量</span>
    registry.addInterceptor(appIntercepter).addPathPatterns(<span class="hljs-string">"/app/**"</span>);
    <span class="hljs-comment">//如果是采用new的方式注入,则Intercepter中不能自动注入成员变量,需要手动获取</span>
    registry.addInterceptor(<span class="hljs-keyword">new</span> TestIntercepter()).addPathPatterns(<span class="hljs-string">"/test/**"</span>);
}

}

使用注解方式

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


public class TestIntercepter extends HandlerInterceptorAdapter {
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> TestComponent testComponent;

<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">preHandle</span><span class="hljs-params">(HttpServletRequest request, HttpServletResponse response, Object handler)</span> <span class="hljs-keyword">throws</span> Exception </span>{

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

    }

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

}

注意

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相关信息

原文地址:https://www.cnblogs.com/naimao/p/13615027.html