-
前言:这两天公司新开了个项目,组长对项目进行了总体规划,其中提到引入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属性上