• 过滤器和拦截器


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

  • 相关阅读:
    .NET Core依赖注入集成Dynamic Proxy
    MediatR-进程内的消息通信框架
    03-EF Core笔记之查询数据
    02-EF Core笔记之保存数据
    01-EF Core笔记之创建模型
    EF Core 基础知识
    CQRS+ES项目解析-Equinox
    CQRS+ES项目解析-Diary.CQRS
    不要让事实妨碍好故事:Facebook精准广告产品与硅谷创业揭秘,4星奇书《混乱的猴子》
    会讲故事的前物理学家万维钢解读、推荐过的书24本,好书一半
  • 原文地址:https://www.cnblogs.com/naimao/p/13615027.html
Copyright © 2020-2023  润新知