当前位置:   article > 正文

Spring Boot3.x 使用SpringDoc生成接口文档-超级完善 + knife4jUI_springboot3 springdoc

springboot3 springdoc

为什么使用SpringDoc

在Springfox3.0停更的两年里,SpringBoot进入3.0时代, SpringFox出现越来越多的问题,最为明显的就是解析器的问题,已经在上文 中解释清楚,这里就不再赘述。
SpringDoc是Spring官方推荐的API,相信不会轻易停更。

如何引入SpringDoc

SpringDoc有多个版本,如果你使用的是SpringBoot3.x,请确保SpringDoc的版本在2.0以上,本文使用的版本是2.0.4,knife4j使用的版本是4.3.0

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4

零、SpringFox的和SpringDoc 区别

在这里插入图片描述

一、直接上代码:集成请求自定义全局鉴权策略参数,自定义分组

依赖knife4j jar

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4

二、使用步骤

1.引入JAVA对象(SwaggerConfig.java,SwaggerGroupConfigEntity.java,SwaggerAutoConfiguration.java)

代码如下:

@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "swagger")
public class SwaggerConfig {
	
	/** 是否开启 true 开启,false 关闭*/
	private String enabled;
	/** 名称 */
	private String title;
	/** 简介 */
	private String description;
	/** 作者 */
	private String author;
	/** 版本 */
	private String version;
	
	/** headers 公共的默认配置 */
//	private Map<String, String> headers = new HashMap<String, String>();
	
	/** 全局鉴权参数 */
	private List<String> security = new ArrayList<>();
	
	/** 定义分组 */
	private List<SwaggerGroupConfigEntity> groupConfigs = new ArrayList<>();
	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
/**
 * 配置信息
 * @author LiuGang
 */
@Getter
@Setter
public class SwaggerGroupConfigEntity implements Serializable{
	/**
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * 分组名称
	 */
	private String group;
	
	/**
	 * 获取的接口请求地址
	 */
	private String pathsToMatch;

	/**
	 * 扫描包地址
	 */
	private String packagesToScan;
	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
/**
 * swggger 接口文档信息
 * @author DEAO-E3 1231
 */
@Configuration
@ConditionalOnProperty(prefix = "swagger", name = "enabled", havingValue = "true", matchIfMissing = true)
public class SwaggerAutoConfiguration  implements BeanFactoryAware {
	
	private static Logger log = LoggerFactory.getLogger(SwaggerAutoConfiguration.class);
	//配置文件
	private SwaggerConfig swaggerConfig;
	private BeanFactory beanFactory;
	private Environment environment;
	
	@Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
	@Autowired
	private void swaggerAutoConfiguration(SwaggerConfig config, Environment environment) {
		this.swaggerConfig = config;
		this.environment = environment;
	}
	//这个是自定义分组和返回鉴权策略的he
	@Bean
	public GroupedOpenApi groupedOpenApi() {
		
		log.info("swggger GroupedOpenApi 接口文档信息 + 加载");
		final OperationCustomizer globalHeader = (operation, handlerMethod) -> {
	        operation.addParametersItem(new HeaderParameter()
	            .$ref("#/components/parameters/testheader"));
	        return operation;
	    };
	    ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory;
	    
	    if(swaggerConfig == null || swaggerConfig.getGroupConfigs() == null || swaggerConfig.getGroupConfigs().size() == 0) {
	    	GroupedOpenApi api = GroupedOpenApi.builder()
	    	    	.group(environment.getProperty("spring.application.name"))
	    	        .pathsToMatch("/**")
	    	        .addOperationCustomizer(globalHeader)
	    	        .addOpenApiCustomizer(getResponseMessages())
	    	        .build();
	    	return api;
	    } else {
    		List<SwaggerGroupConfigEntity> groupConfigs = swaggerConfig.getGroupConfigs();
    		for(SwaggerGroupConfigEntity entity : groupConfigs) {
    			GroupedOpenApi api = GroupedOpenApi.builder()
	    	    	.group(entity.getGroup())
	    	        .pathsToMatch(entity.getPathsToMatch())
	    	        .packagesToScan(entity.getPackagesToScan())
	    	        .addOperationCustomizer(globalHeader)
	    	        .addOpenApiCustomizer(getResponseMessages())
	    	        .build();
    			//注册成bean
    			configurableBeanFactory.registerSingleton(entity.getGroup(), api);
    		}
	    }
	    return null;
	}
	
	
	@Bean
    public OpenAPI openAPI() {
		log.info("swggger OpenAPI接口文档信息 + 加载");
		OpenAPI openApi  = new OpenAPI();
		//基础参数信息
		openApi.setInfo(getInfo());
		//指定安全模式参数
		securitySchemes(openApi);
		return openApi;
    }
	
	/**
     * 安全模式,这里指定token通过Authorization头请求头传递
     */
    private void securitySchemes(OpenAPI openApi) {
        if(swaggerConfig != null && swaggerConfig.getSecurity() != null && swaggerConfig.getSecurity().size() > 0) {
        	swaggerConfig.getSecurity().forEach(string->{
        		SecurityScheme securityScheme = new SecurityScheme()
    				.name(string)
//    				.scheme("bearer")
    				.bearerFormat("JWT")
    				.type(SecurityScheme.Type.HTTP)
    				.in(SecurityScheme.In.HEADER)
    				.description("安全模式-指定参数:" + string);
        		openApi.schemaRequirement(string, securityScheme)
    			.addSecurityItem(new SecurityRequirement().addList(string));
        	});
        }
    }
	
	private Info getInfo() {
    	if(swaggerConfig == null) {
    		swaggerConfig = new SwaggerConfig();
    	}
    	Contact contact = new Contact()
    			.name(!StringUtils.hasLength(swaggerConfig.getAuthor()) ? "作者" : swaggerConfig.getAuthor());
        Info info = new Info()
	        	.title(!StringUtils.hasLength(swaggerConfig.getTitle()) ? "接口文档" : swaggerConfig.getTitle())
	        	.version(!StringUtils.hasLength(swaggerConfig.getVersion()) ? "接口文档" : swaggerConfig.getVersion())
	            .description(!StringUtils.hasLength(swaggerConfig.getDescription()) ? "更多请咨询服务开发者。" : swaggerConfig.getDescription())
				.contact(contact);
        return info;
    }
	
	/**
	 * 设置全局响应状态
	 * @return
	 */
	private OpenApiCustomizer getResponseMessages() {
	    return openApi -> {
	        openApi.getPaths().values().forEach(pathItem ->
	            pathItem.readOperations().forEach(operation -> {
	            	//返回 响应状态
	                ApiResponses apiResponses = operation.getResponses();
	                
	                String codeString = "其他状态码请参考说明";
	                String msgString = "";
	                
	                for (ResultCode enums : ResultCode.values()) {
	                	if(enums.getCode() != 200) {
	                		msgString += enums.getCode() + "=" + enums.getMsg() + ";";
//	                		apiResponses.addApiResponse(String.valueOf(enums.getCode()),
//	                				new ApiResponse().description(enums.getMsg()));
// 此处是自定义状态码返回,我这里是用自定义枚举 循环返回成一行的,,可以自行转换 和定义多行
	                	}
	                }
	                apiResponses.addApiResponse(codeString,
            				new ApiResponse().description(msgString));
	                
	                //鉴权指定参数 Security
	                if(swaggerConfig != null && swaggerConfig.getSecurity() != null && swaggerConfig.getSecurity().size() > 0) {
	                	List<SecurityRequirement> securityList = new ArrayList<>();
	                	swaggerConfig.getSecurity().forEach(string->{
	                		securityList.add(new SecurityRequirement().addList(string));
	                	});
	                	operation.security(securityList);
	                }
	            }));
	    };
	}
	
	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144

2.配置 yml

代码如下(示例):

#接口文档配置        
swagger:
  enabled: true
  title: 测试接口文档11
  description: 简介信息介绍11
  author: 作者lg
  version: 1.0.1
   #全局鉴权策略参数 
  security:
    - Authorization
    - user-token
  # 定义分组
  groupConfigs:
    - group: 测试的
      pathsToMatch: '/**'
      packagesToScan: com.pub.test.controller
    - group: 测试的22
      pathsToMatch: '/**'
      packagesToScan: com.pub.test.controller
      
springdoc:
  swagger-ui:
    enabled: ${swagger.enabled}
  api-docs:
    #是否开启文档功能
    enabled: ${swagger.enabled}
    #自定义的文档api元数据访问路径。默认访问路径是/v3/api-docs
    path: /v3/api-docs
  #默认平展参数 - 开启query参数实体接口按query传参模式
  default-flat-param-object: true
  #定义分组 -- 建议用 swagger.groupConfigs - 自定义分组,,如果用此处,请将groupedOpenApi() 这个bean删除,将不再支持自定义返回状态和登录策略的header
  #group-configs:
  #  - group: '测试的'
  #    paths-to-match: '/**'
  #    packages-to-scan: com.pub.test.controller
  #  - group: '测试的2'
  #    paths-to-match: '/**'
  #    packages-to-scan: com.pub.test.controller
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

访问地址:http://127.0.0.1:8082/doc.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意事项: 数据返回不响应二级目录文档,解决办法:将顶级对象中的 注解@Schema去掉就行了


总结---->(微服务集成knife4j 请等待更新)

以上就是今天要讲的内容,本文仅仅简单集成了SpringDoc的使用,有不明白的赶紧下方留言。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/488991
推荐阅读
相关标签
  

闽ICP备14008679号