• 前言:这两天公司新开了个项目,组长对项目进行了总体规划,其中提到引入Swagger,私下研究了一下基于knife4j增强的Swagger3.0.0(其实就是美化了一下页面),很多文章都说引入很简单,而且基本都是三个步骤引依赖,创建配置类,启动项目看效果,我跟着操作了一番,结过嘎嘎报错,所以写篇文章记录一下。

  • 技术栈:springboot 2.6.4+knife4j-spring-boot-statter3.0.3

  • 1、引入依赖

    gradle格式:

"com.github.xiaoymin:knife4j-spring-boot-starter:3.0.3"。

  • 2、初始化配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
 * @author :NanMu
 * @date :Created in 15:11 2022/5/16
 * @description :Swagger配置
 * @version: 1.0
 */
@Configuration
@EnableOpenApi
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("XXX管理系统")
                .description("XXX管理系统 API接口文档")
                .license("XXX")
                .licenseUrl("http://127.0.0.1:8080")
                .version("1.0")
                .build();
    }
}

  • 3、过滤器放过Swagger相关路径

String[] swaggerUrl = new String[]{
        "/swagger-ui/**",
        "/swagger-resources/**",
        "/v2/api-docs",
        "/v3/api-docs",
        "/webjars/**",
        "/doc.html",  // 在原有的swagger3放行基础上加上 /doc.html
};

  • 4、效果展示(访问路径:域名+/doc.html)

5、常见问题及解决方案

(1)启动失败,提示原因如下:Application run failed,Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException。

网上很多文章分析及解决方案为:

原因springboot2.6.0中将SpringMVC 默认路径匹配策略从AntPathMatcher 更改为PathPatternParser,导致出错,解决办法是切换为原先的AntPathMatcher,或者降低springboot版本到2.6.0以下。

  切换为原先的AntPathMatcher在yml中添加配置配置方式为:

    spring:   

       mvc:

         pathmatch:

           matching-strategy: ant_path_matcher

        首先项目不可能随意降低使用的springboot版本,其次本人切换为原先的AntPathMatcher仍然报错。后经过多方查找,发现解决方案为:在配置类中注入如下bean。

@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
    return new BeanPostProcessor() {

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
                customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
            }
            return bean;
        }

        private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
            List<T> copy = mappings.stream()
                    .filter(mapping -> mapping.getPatternParser() == null)
                    .collect(Collectors.toList());
            mappings.clear();
            mappings.addAll(copy);
        }

        @SuppressWarnings("unchecked")
        private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
            try {
                Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
                field.setAccessible(true);
                return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
            } catch (IllegalArgumentException | IllegalAccessException e) {
                throw new IllegalStateException(e);
            }
        }
    };
}

(2)访问Swagger地址(http://localhost:8081/doc.html) 404.

经分析发现是拦截配置的有问题,正确配置如下:

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

(3)访问/doc.html,spring security提示没有权限访问/favicon.ico

经分析发现是spring security配置的有问题,增加放过/favicon.ico

  • 6、常见注解

    @Tag(name = “接口类描述”) Controller 类上

    @Operation(summary =“接口方法描述”) Controller 方法上

    @Parameters Controller 方法上

    @Parameter(description=“参数描述”) Controller 方法上 @Parameters 里

    @Parameter(description=“参数描述”) Controller 方法的参数上

    @Schema DTO类上

    @Schema

     忽略信息:

    @Parameter(hidden = true)

    或@Operation(hidden = true)

    或 @Hidden -DTO属性上

  

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐