SpringMVC—拦截器


一、概念

浏览器访问资源流程:

  • 拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
  • 作用:
    • 在指定的方法调用前后执行预先设定的代码
    • 阻止原始方法的执行
  • 拦截器与过滤器的区别
    • 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
    • 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强

二、入门案例

  1. 声明拦截器的bean,并实现HandlerInterceptor接口(注意:扫描加载bean):

    @Component
    public class ProjectInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("ProjectInterceptor.preHandle()");
            return true;
        };
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("ProjectInterceptor.postHandle()");
        };
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("ProjectInterceptor.afterCompletion()");
        };
    };
    
  2. 定义配置类,继承WebMvcConfigurationSupport,实现addInterceptor方法并添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个(注意:扫描加载配置):

    @Configuration
    public class SpringMvcSupport extends WebMvcConfigurationSupport {
        @Autowired
        private ProjectInterceptor projectInterceptor;
        
        @Override
        protected void addInterceptors(InterceptorRegistry registry){
            registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
        };
    };
    

SpringMvcConfig配置类与SpringMvcSupport配置类合并:

使SpringMvcConfig配置类实现WebMvcConfigurer接口,并在其中重写相关方法

(此方法有缺点:侵入性较强)

@Configuration
@ComponentScan({"com.cikian.controller"};)
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ProjectInterceptor projectInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
    };

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
        registry.addResourceHandler("/index.html").addResourceLocations("/index.html");
    };
};

三、拦截器参数

1. 前置处理

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

        return true;
    };
  • 参数:
    • request:请求对象
    • response:响应对象
    • handler:被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装
  • 返回值:
    • 返回值为false,被拦截的处理器将不再执行

2. 后置处理

public void postHandle(HttpServletRequest request, 
                       HttpServletResponse response, 
                       Object handler, 
                       ModelAndView modelAndView)
        throws Exception {
};
  • 参数:
    • request:请求对象
    • response:响应对象
    • handler:被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装
    • modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整

3. 完成后处理

public void afterCompletion(HttpServletRequest request, 
                            HttpServletResponse response, 
                            Object handler, 
                            Exception ex)
        throws Exception {
};
  • 参数:
    • request:请求对象
    • response:响应对象
    • handler:被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装
    • ex:如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理

四、拦截器工作流程分析

五、多拦截器执行顺序

  • 当配置多个拦截器时,形成拦截器链
  • 拦截器链的运行顺序参照拦截器添加顺序为准
  • 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
  • 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作

拦截器链的运行顺序:

  • preHandle:与配置顺序相同,必定运行
  • postHandle:与配置顺序相反,可能不运行
  • afterCompletion:与配置顺序相反,可能不运行

文章作者: Cikian
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Cikian !
评论
  目录