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