小工具知识网

当前位置: 首页 > 行业知识 > springboot:通过WebMvcConfigurer和HandlerInterceptor配置多个拦截器

行业知识

springboot:通过WebMvcConfigurer和HandlerInterceptor配置多个拦截器

2026-11-15 13:03:57 来源:互联网转载

1、创建俩个类实现HandlerInterceptor接口

会实现下面三个方法:

preHandle:调用Controller某个方法之前

postHandle:Controller之后调用,视图渲染之前,如果控制器Controller出现了异常,则不会执行此方法

afterCompletion:不管有没有异常,这个afterCompletion都会被调用,用于资源清理

@Slf4j@Componentpublic class OneHandlerInterceptor implements HandlerInterceptor {    /**     * 后处理回调方法,实现处理器(controller)的后处理,但在渲染视图之前     * 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理     */    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);    }    /**     * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,     * 如性能监控中我们可以在此记录结束时间并输出消耗时间,     * 还可以进行一些资源清理,类似于try-catch-finally中的finally,     * 但仅调用处理器执行链中     */    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);    }    /**     * 预处理回调方法,实现处理器预处理     * 返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或者处理器     */    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        //如果不是映射到方法直接放行        if(!(handler instanceof HandlerMethod)){            return true;        }        // todo 还可配置白名单黑名单        /**         * 可配合接口注解使用         * 1、在接口上添加角色注解         * 2、通过判断请求接口上是否有注解         * 3、获取用户角色,判断是否与接口角色配对         */        HandlerMethod handlerMethod = (HandlerMethod)handler;        Method method = handlerMethod.getMethod();        if (method.isAnnotationPresent(ActionRoles.class)) {            //方法上面是否有某个角色注解?            ActionRoles annotation = method.getAnnotation(ActionRoles.class);            String[] roles = annotation.value();        }        return true;    }}

2、Web配置文件中注入拦截器

在实现WebMvcConfigurer之后可以选择你要重写的方法,这里重写addInterceptors这个方法来添加自定义的拦截器。

addInterceptor:用于添加你自定义的拦截器实例

addPathPatterns:用于添加要拦截的url,可以写多个。

excludePathPatterns:用于添加不需要拦截的url,可以写多个。

@Configurationpublic class WebWvcConfig implements WebMvcConfigurer {    @Autowired    private OneHandlerInterceptor oneHandlerInterceptor;    @Autowired    private TwoHandlerInterceptor twoHandlerInterceptor;    @Override    public void addResourceHandlers(ResourceHandlerRegistry registry) {        /*            指定静态资源的访问路径前缀以及静态资源所处路径不被拦截            然后在添加自定义拦截器时忽略静态资源的路径前缀         */        //第一个方法设置访问路径前缀,第二个方法设置资源路径        registry.addResourceHandler("/resources/**","/public/**")                .addResourceLocations("classpath:/resources/","classpath:/public/");    }    @Override    public void addInterceptors(InterceptorRegistry registry) {        // 拦截所有路径   多个拦截器组成一个拦截器链        // 注册自定义两个拦截器        // addPathPatterns  用来添加拦截规则,/** 表示拦截所有请求  /*/表示拦截目录        // excludePatterns  用户排除拦截        //拦截器的拦截顺序,是按照Web配置文件中注入拦截器的顺序执行的        registry.addInterceptor(oneHandlerInterceptor)                .addPathPatterns("/**")                .excludePathPatterns("/login")                .excludePathPatterns("/open/**")                .excludePathPatterns("/api/**");        registry.addInterceptor(twoHandlerInterceptor)                .addPathPatterns("/**")                .excludePathPatterns("/login")                .excludePathPatterns("/open/**")                .excludePathPatterns("/api/**");    }}

这里需要注意,在springboot中使用多个继承WebMvcConfigurationSupport的类是行不通的,而且使用注解@configuration去加载配置类只能挂载一个继承WebMvcConfigurationSupport,如果有多个而且在不同级包中,那么会优先加载最外层包的配置类,其他继承WebMvcConfigurationSupport的类是不会加载。

原因:WebMvcConfigurationSupport调用模板类resourceHandlerMapping生成bean,其实是调用父类的模板类,去加载下一个发现已经有了就不会调用resourceHandlerMapping(bean的id相同)。

但貌似这种情况的解决方法就是都实现父类 webMvcConfigurer 接口 ,这样都能挂载,但试了不太行,原因也不知了。因此保险还是尽可能不去实现多个webMvcConfigurer 吧。

上一篇:代号莺服务器怎么没有?

下一篇:元素之诗服务器怎么交易?