资讯专栏INFORMATION COLUMN

spring boot 集成swagger并且使用拦截器的配置问题

fsmStudy / 3099人阅读

摘要:另外的解决方案网上还有另外一种说法,可以实现接口,代码如下用于添加拦截规则,先把所有路径都加入拦截,再一个个排除自定义规则,如果遇到,则把泛型类转成通用服务易保科技但是这种配置想要生效,必须加注解,不然不起作用。

最近同事问我,spring boot集成了swagger,但是在使用拦截器的时候遇到了问题,页面无法访问。经过研究解决了这个问题。

配置问题解决

集成swagger就不啰嗦了,网上到处都是,直接看配置。

同事从网上找到的配置:

import com.xxx.xxxx.xxx.xxx.LoginInterceptor;
import com.fasterxml.classmate.TypeResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.WildcardType;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.Collections;

import static springfox.documentation.schema.AlternateTypeRules.newRule;

@Configuration
@EnableSwagger2
public class Swagger2Config extends WebMvcConfigurationSupport {
    @Autowired
    private TypeResolver typeResolver;

    @Bean
    public Docket productApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.xxx.xxx.controller"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(metaData())
                .alternateTypeRules( //自定义规则,如果遇到DeferredResult,则把泛型类转成json
                        newRule(typeResolver.resolve(DeferredResult.class,
                                typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
                                typeResolver.resolve(WildcardType.class)))
                ;
    }

    private ApiInfo metaData() {
        return new ApiInfoBuilder()
                .title("通用服务 APIs")
                /*.description(""REST API for Online Store"")*/
                .version("1.0.0")
               /* .license("Apache License Version 2.0")
                .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0"")*/
                .contact(new Contact("易保科技", "", "mail@mail"))
                .build();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
        super.addResourceHandlers(registry);
    }
}

这是他从网上找到的拦截器的配置:

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    

    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(new LoginInterceptor())
                // addPathPatterns 用于添加拦截规则 , 先把所有路径都加入拦截, 再一个个排除
                .addPathPatterns("/**")
                .excludePathPatterns(Collections.singletonList("/swagger-ui.html"));
        super.addInterceptors(registry);
    }

}

现在的测试结果就是,打开http://host:port/path/swagger-ui.html,就是一个空白页面,无法使用,现在要解决的就是这个问题。

打开谷歌浏览器的调试控制台,查看network,如图:

可以明显看出,页面加载数据的时候,并没有报什么错误,只是加载的资源都被拦截器拦截了,无法加载资源,可想而知,资源都被拦截器拦截了。

我分析了一下,加载资源的路径,修改了一下拦截器资源配置:

 @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                // addPathPatterns 用于添加拦截规则 , 先把所有路径都加入拦截, 再一个个排除
                .addPathPatterns("/**")
                .excludePathPatterns("/swagger-ui.html")
                .excludePathPatterns("/swagger-resources/**")
                .excludePathPatterns("/error")
                .excludePathPatterns("/webjars/**");
    }

另外两个类实际是同一个作用,所以合并两个类:

@Configuration
@EnableSwagger2
public class TestMVCConfig extends WebMvcConfigurationSupport {

    @Resource
    private TypeResolver typeResolver;


    @Resource
    private LoginInterceptor loginInterceptor;


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                // addPathPatterns 用于添加拦截规则 , 先把所有路径都加入拦截, 再一个个排除
                .addPathPatterns("/**")
                .excludePathPatterns("/swagger-ui.html")
                .excludePathPatterns("/swagger-resources/**")
                .excludePathPatterns("/error")
                .excludePathPatterns("/webjars/**");
    }


    @Bean
    public Docket productApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.xxx.xxx.controller"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(metaData())
                .alternateTypeRules( //自定义规则,如果遇到DeferredResult,则把泛型类转成json
                        newRule(typeResolver.resolve(DeferredResult.class,
                                typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
                                typeResolver.resolve(WildcardType.class)))
                ;
    }

    private ApiInfo metaData() {
        return new ApiInfoBuilder()
                .title("通用服务 APIs")
                /*.description(""REST API for Online Store"")*/
                .version("1.0.0")
                /* .license("Apache License Version 2.0")
                 .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0"")*/
                .contact(new Contact("易保科技", "", "mail@mail"))
                .build();
    }
}

这样就没有问题了。

另外的解决方案

网上还有另外一种说法,可以实现WebMvcConfigurer接口,代码如下:

@Configuration
@EnableWebMvc
@EnableSwagger2
public class WebMVCConfig implements WebMvcConfigurer{

    @Resource
    private TypeResolver typeResolver;

    @Resource
    private LoginInterceptor loginInterceptor;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        List excludePathPatterns = new ArrayList<>();
        excludePathPatterns.add("/swagger-ui.html");
        excludePathPatterns.add("/swagger-resources/**");
        excludePathPatterns.add("/error");
        excludePathPatterns.add("/webjars/**");

        // addPathPatterns 用于添加拦截规则 , 先把所有路径都加入拦截, 再一个个排除
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(excludePathPatterns);
    }

    @Bean
    public Docket productApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.xx.sss.controller"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(metaData())
                .alternateTypeRules( //自定义规则,如果遇到DeferredResult,则把泛型类转成json
                        newRule(typeResolver.resolve(DeferredResult.class,
                                typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
                                typeResolver.resolve(WildcardType.class)))
                ;
    }


    private ApiInfo metaData() {
        return new ApiInfoBuilder()
                .title("通用服务 APIs")
                /*.description(""REST API for Online Store"")*/
                .version("1.0.0")
                /* .license("Apache License Version 2.0")
                 .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0"")*/
                .contact(new Contact("易保科技", "", "mail@mail"))
                .build();
    }
}

但是这种配置想要生效,必须加@EnableWebMvc注解,不然不起作用。为什么?
官方源码注释:

/**
 * Defines callback methods to customize the Java-based configuration for
 * Spring MVC enabled via {@code @EnableWebMvc}.
 *
 * 

{@code @EnableWebMvc}-annotated configuration classes may implement * this interface to be called back and given a chance to customize the * default configuration. *

通过@enableWebMVC启用Spring MVC,自定义基于Java config 定义回调方法。
@EnableWebMVC带注释的配置类可以实现这个接口自定义默认配置。

当然如果你觉得自己的配置没问题,但是仍然不起作用,这时候该怎么办?请按照一下步骤debug:
1、找到InterceptorRegistration类;
2、找到addInterceptor方法和excludePathPatterns方法,打上断点;
3、debug模式启动项目;

如果没有进入断点,那就说明你的配置根本没有起到作用,看看注解是否没写。

如果进入了断点,就要看看断点处传进来的参数是否是你配置的参数,不是那就是有问题,这时候再根据参数查找问题。

这样基本就能解决问题了。

总结

网上很多东西都是抄来抄去,也不知道有没有验证,让很多人摸不着头脑。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74168.html

相关文章

  • ApiBoot - ApiBoot Security Oauth 依赖使用文档

    摘要:如果全部使用默认值的情况话不需要做任何配置方式前提项目需要添加数据源依赖。获取通过获取启用在使用格式化时非常简单的,配置如下所示开启转换转换时所需加密,默认为恒宇少年于起宇默认不启用,签名建议进行更换。 ApiBoot是一款基于SpringBoot1.x,2.x的接口服务集成基础框架, 内部提供了框架的封装集成、使用扩展、自动化完成配置,让接口开发者可以选着性完成开箱即...

    Tonny 评论0 收藏0
  • Java | Spring Boot Swagger2 集成REST ful API 生成接口文档

    摘要:集成生成接口文档原文简介由于的特性,用来开发变得非常容易,并且结合来自动生成文档变得方便快捷。使用生成,我们可以得到交互式文档。听过与的结合,生成更加完备的文档。接下来将基于与搭建完整的文档系统。 Spring Boot Swagger2 集成REST ful API 生成接口文档 原文 简介 由于Spring Boot 的特性,用来开发 REST ful 变得非常容易,并且结合 Sw...

    joyvw 评论0 收藏0
  • SpringCloud核心教程 | 第四篇:服务注册与发现 Consul篇

    摘要:下一篇介绍基于的服务注册与调用。服务提供者工程配置这里服务提供者是使用之前进阶教程第三篇整合连接池以及监控改造而来,这里一样的部分就不再重复说明,下面将说明新增的部分。 Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分...

    Xufc 评论0 收藏0

发表评论

0条评论

fsmStudy

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<