【问题解决】解决 swagger2 默认地址失效

2023-08-30 15:11:56 浏览数 (1)

前言

有段时间没用 Java 写过项目了,今天因为需求要搭建一个小项目,果然是略显生疏,一路磕磕碰碰的,不过总算都是让我解决了。

回归正题,本篇博文要讲的是,关于配置好 swagger2 之后,访问其页面却被告诉页面不存在,即默认地址失效的问题。

当然也顺带讲解一下 SpringBoot 和 Springfox 的版本兼容性问题。以下就先讲解如何简单地解决版本兼容性问题。

修改路径匹配策略

先介绍一下相关的配置信息,SpringBoot 用的版本是 2.7.10,maven 是 3.6.1,用的是阿里云的镜像。

swagger2 的安装配置如下:

代码语言:javascript复制
<!--swagger2-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

然后新建一个 SwaggerConfig.java 类,用于配置一些与 Swagger2 相关的内容,如下:

代码语言:javascript复制
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket examApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName("xxx")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sidiot.xxx.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("xxx")
                .description("xxx")
                .contact(new Contact("sid10t.", "https://www.sid10t.com", "e-mail"))
                .version("1.0.0")
                .build();
    }
}

然后将程序启动,发现报错了:

错误原因是 org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException

这个异常表示在启动 Spring 应用程序上下文时,documentationPluginsBootstrapper 这个 Bean 启动失败,并且嵌套异常是 NullPointerException。通常这种错误发生在调用一个空对象的方法或者访问一个空对象的属性时。

这是因为 SpringBoot 在 2.6.1 之后,SpringMVC 处理程序映射匹配请求路径的默认策略已从 AntPathMatcher 更改为 PathPatternParser。而 Springfox 使用的路径匹配还是 AntPathMatcher,因此导致了这个错误的发生。

那么这里只需要在配置文件 application.properties 中,重新修改策略即可:

代码语言:javascript复制
spring.mvc.pathmatch.matching-strategy=ant-path-matcher

.yml 的小伙伴这样改:

代码语言:javascript复制
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

修改完成之后就能正常访问到页面了!

关于 SpringBoot 在 2.6.1 之后的一些变化,可以参考这篇博文:Springboot 升级到 2.6.1 的坑;

用这个方法解决兼容性问题的小伙伴,是不会碰到 swagger2 默认地址失效的问题的,用下面一种方法解决兼容性问题就会遇到!

使用 @EnableWebMvc 注解

是的,除了上述提到的修改匹配策略之外,还有一种方式也能解决兼容性问题,那就是使用注解 @EnableWebMvc

我们只需要在启动类上加上 @EnableWebMvc 这个注解就可以了:

代码语言:javascript复制
@EnableWebMvc
@SpringBootApplication
public class xxxApplication {

    public static void main(String[] args) {
        SpringApplication.run(xxxApplication.class, args);
    }

}

添加上注解之后,启动我们的程序看一看,发现没有报错,是正常运行的,在打开 swagger 的页面瞅瞅,

发现找不到页面,在看看控制台也是如此:

代码语言:javascript复制
2023-04-13 17:34:54.885  WARN 17948 --- [nio-8080-exec-1] o.s.web.servlet.PageNotFound             : No mapping for GET /swagger-ui.html

试了试其他相关的 url 路径也是找不到,这是为什么呢?

先简单介绍一下 @EnableWebMvc 这个注解:

@EnableWebMvc 是 SpringMVC 框架中的一个注解,它的作用是开启对 SpringMVC 的支持。

具体来说,使用 @EnableWebMvc 注解会导入一系列与 SpringMVC 相关的配置类,并且会自动注册多个关键组件,如 HandlerMapping、HandlerAdapter、ViewResolver 等。这些组件可以让开发者方便地处理 HTTP 请求和响应、实现 MVC 模式以及生成视图。

但需要注意的是,如果使用了 @EnableWebMvc 注解,则默认情况下会禁用 SpringBoot 中的自动配置,因为 @EnableWebMvc 已经提供了类似的功能。如果想要同时使用 SpringBoot 的自动配置和@EnableWebMvc,可以通过在配置类上添加 @Import({WebMvcAutoConfiguration.class}) 注解来实现。

Swagger 通常是使用 springfox-swagger2 和 springfox-swagger-ui 这两个库来实现的。在使用 @EnableWebMvc 注解时,会覆盖掉 SpringBoot 自动配置中的 WebMvcAutoConfiguration,可能导致 Swagger 的默认地址 /swagger-ui.html 失效。因为在 WebMvcAutoConfiguration 类中有一个关于 Swagger 的默认配置项:

代码语言:javascript复制
@Configuration
@ConditionalOnClass({ UiConfiguration.class })
@EnableConfigurationProperties(SwaggerUiProperties.class)
public class SwaggerUiWebMvcConfiguration {
    // ...
}

这个类在提供了许多 Swagger 相关的默认配置,包括默认的 UI 界面路径 /swagger-ui.html。但是,当添加 @EnableWebMvc 注解后,SpringMVC 将覆盖掉这个类的配置,进而导致 Swagger 的默认 UI 界面无法使用。

解决这个问题的方法是手动配置 Swagger 相关的 Bean,并指定 Swagger UI 的访问路径和资源文件位置。比如可以在配置类中添加以下内容:

代码语言:javascript复制
@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api() { 
        return new Docket(DocumentationType.SWAGGER_2).select()
          .apis(RequestHandlerSelectors.any())
          .paths(PathSelectors.any())
          .build();
    }

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

这样就可以手动配置 Swagger 相关的 Bean,并指定 Swagger UI 的访问路径和资源文件位置,从而解决 @EnableWebMvc 导致 Swagger 默认地址失效的问题。

后记

以上就是 解决 swagger2 默认地址失效 的全部内容了,希望对大家有所帮助!

0 人点赞