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

文章介绍了SpringFox问题后的替代方案SpringDoc,包括如何在SpringBoot3.x中引入SpringDoc2.0+,以及如何配置全局鉴权、自定义分组和API文档。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么使用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>

零、SpringFox的和SpringDoc 区别

在这里插入图片描述

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

依赖knife4j jar

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>

二、使用步骤

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<>();
	
}
/**
 * 配置信息
 * @author LiuGang
 */
@Getter
@Setter
public class SwaggerGroupConfigEntity implements Serializable{
	/**
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * 分组名称
	 */
	private String group;
	
	/**
	 * 获取的接口请求地址
	 */
	private String pathsToMatch;

	/**
	 * 扫描包地址
	 */
	private String packagesToScan;
	
}
/**
 * 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(