以前 Knife4j 还是 Swagger 的一个前端皮肤,现在已经变成了一个增强解决方案了

这个是 Knife4j 官方的介绍:Knife4j 是一个集 Swagger2 和 OpenAPI3 为一体的增强解决方案

https://doc.xiaominfo.com/ 是 Knife4j 的官方地址。

快速入门很简单,直接看官方文档吧:https://doc.xiaominfo.com/docs/action/springboot

Model 名称重名解决

Model 名称自动防止重名:比如前面使用 Swagger 的时候遇到的重名 文档,Knife4j 也存在这个问题

只不过 Knife4j 对 model 的命名有要求,类全限定名称里面有特殊符号 . 把它换一下就行了。
比如下面这个配置

  1. // ~ swagger API 文档 ==========================
  2. implementation "io.springfox:springfox-boot-starter:3.0.0"
  3. implementation 'com.github.xiaoymin:knife4j-spring-boot-starter:2.0.9'
  1. package cn.mrcode.autoconfig;
  2. import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import springfox.documentation.builders.ApiInfoBuilder;
  7. import springfox.documentation.builders.PathSelectors;
  8. import springfox.documentation.builders.RequestHandlerSelectors;
  9. import springfox.documentation.spi.DocumentationType;
  10. import springfox.documentation.spi.schema.TypeNameProviderPlugin;
  11. import springfox.documentation.spring.web.plugins.Docket;
  12. import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
  13. /**
  14. * @author mrcode
  15. * @date 2022/11/2 19:35
  16. */
  17. @Configuration
  18. @EnableSwagger2WebMvc
  19. public class Knife4jConfiguration {
  20. /*引入Knife4j 提供的扩展类*/
  21. private final OpenApiExtensionResolver openApiExtensionResolver;
  22. @Autowired
  23. public Knife4jConfiguration(OpenApiExtensionResolver openApiExtensionResolver) {
  24. this.openApiExtensionResolver = openApiExtensionResolver;
  25. }
  26. @Bean(value = "defaultApi2")
  27. public Docket defaultApi2() {
  28. Docket docket = new Docket(DocumentationType.SWAGGER_2)
  29. .apiInfo(new ApiInfoBuilder()
  30. .title("系统 RESTful APIs")
  31. .description("API 文档")
  32. //.termsOfServiceUrl("http://www.xx.com/")
  33. .version("1.0")
  34. .build())
  35. //分组名称
  36. // .groupName("2.X版本")
  37. .select()
  38. //这里指定Controller扫描包路径
  39. .apis(RequestHandlerSelectors.basePackage("cn.mrcode.web.controller"))
  40. .paths(PathSelectors.any())
  41. .build()
  42. //赋予插件体系
  43. .extensions(openApiExtensionResolver.buildExtensions("default"));
  44. ;
  45. return docket;
  46. }
  47. @Bean
  48. public TypeNameProviderPlugin typeNameProviderPlugin() {
  49. return new MyTypeNameProviderPlugin();
  50. }
  51. }
  1. package cn.mrcode.autoconfig;
  2. import org.springframework.core.annotation.Order;
  3. import springfox.documentation.spi.DocumentationType;
  4. import springfox.documentation.spi.schema.TypeNameProviderPlugin;
  5. import springfox.documentation.swagger.common.SwaggerPluginSupport;
  6. /**
  7. * @author mrcode
  8. * @date 2022/11/2 17:50
  9. */
  10. @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER - 100)
  11. public class MyTypeNameProviderPlugin implements TypeNameProviderPlugin {
  12. @Override
  13. public String nameFor(Class<?> type) {
  14. // 这里将特殊字符 . 换成下划线
  15. return type.getName().replaceAll("\\.", "_");
  16. }
  17. @Override
  18. public boolean supports(DocumentationType delimiter) {
  19. return true;
  20. }
  21. }

下面是 yml 中的配置(其实不太重要,和本次要解决的重名问题没有任何关系,算是一个入门 demo 吧)

  1. knife4j:
  2. enable: true
  3. # 生产环境屏蔽资源
  4. production: false
  5. documents:
  6. - name: 使用 API 必读
  7. locations: classpath:api-markdowns/*

model 命名的不同下面截图有比较
![NVRRPTVG4W$}R6(UT1CW[8.png](https://cdn.nlark.com/yuque/0/2022/png/651749/1667439480616-69855c0f-7ba9-4b28-abec-4becd6f3b2c0.png#averageHue=%23fdfcfc&clientId=u98f12cef-38bb-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=paste&height=708&id=ub861dcc4&margin=%5Bobject%20Object%5D&name=NVRRPT%60VG4W%24%7DR6%28UT1CW%5B8.png&originHeight=885&originWidth=1568&originalType=binary&ratio=1&rotation=0&showTitle=false&size=171950&status=error&style=none&taskId=ucd076dcd-bb84-4046-842a-d4c12140c1f&title=&width=1254.4)<br />通过对比发现:只要$ref值没有#/definitions`开头的路径,在下图的请求参数和响应参数里面就看不到具体的参数信息。
image.png