1.自定义OpenAPIService;
import cn.hutool.core.collection.CollectionUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.github.xiaoymin.knife4j.core.conf.ExtensionsConstants;
import io.swagger.v3.core.util.AnnotationsUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.tags.Tags;
import io.swagger.v3.oas.models.OpenAPI;
import org.springdoc.core.OpenAPIService;
import org.springdoc.core.PropertyResolverUtils;
import org.springdoc.core.SecurityService;
import org.springdoc.core.SpringDocConfigProperties;
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
import org.springdoc.core.providers.JavadocProvider;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CustomOpenAPIService extends OpenAPIService {
private final PropertyResolverUtils propertyResolverUtils;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public CustomOpenAPIService(Optional<OpenAPI> openAPI, SecurityService securityParser, SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils, Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers, Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers, Optional<JavadocProvider> javadocProvider) {
super(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider);
this.propertyResolverUtils = propertyResolverUtils;
}
/**
* 重写tags获取方法
*/
@Override
public void buildTagsFromClass(Class<?> beanType, Set<io.swagger.v3.oas.models.tags.Tag> tags, Set<String> tagsStr, Locale locale) {
Set<Tags> tagsSet = AnnotatedElementUtils.findAllMergedAnnotations(beanType, Tags.class);
Set<io.swagger.v3.oas.annotations.tags.Tag> classTags = tagsSet.stream().flatMap((x) -> Stream.of(x.value())).collect(Collectors.toSet());
classTags.addAll(AnnotatedElementUtils.findAllMergedAnnotations(beanType, io.swagger.v3.oas.annotations.tags.Tag.class));
if (CollectionUtil.isNotEmpty(classTags)) {
tagsStr.addAll(classTags.stream().map((tag) -> this.propertyResolverUtils.resolve(tag.name(), locale)).collect(Collectors.toSet()));
List<Tag> allTags = new ArrayList<>(classTags);
this.addTags(beanType, allTags, tags, locale);
}
}
/**
* 按照父类的方法,添加了beanType,以便于获取类上的其他注解
*/
private void addTags(Class<?> beanType, List<Tag> sourceTags, Set<io.swagger.v3.oas.models.tags.Tag> tags, Locale locale) {
ApiSupport apiSupport = AnnotationUtils.findAnnotation(beanType, ApiSupport.class);
// 如果 @Tag 不想写 description 的话,可以把 true 改成 false
Optional<Set<io.swagger.v3.oas.models.tags.Tag>> optionalTagSet = AnnotationsUtils.getTags(sourceTags.toArray(new Tag[0]), true);
optionalTagSet.ifPresent(tagsSet -> tagsSet.forEach(tag -> {
tag.name(propertyResolverUtils.resolve(tag.getName(), locale));
tag.description(propertyResolverUtils.resolve(tag.getDescription(), locale));
// 把获取到的ApiSupport附加到tag的扩展属性上
if (apiSupport != null) {
tag.addExtension(ExtensionsConstants.EXTENSION_ORDER, apiSupport.order());
}
if (tags.stream().noneMatch(t -> t.getName().equals(tag.getName()))) {
tags.add(tag);
}
}));
}
}
2.把自定义OpenAPIService注入bean
/**
* 自定义 OpenAPI 处理器
*/
@Bean
public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI,
SecurityService securityParser,
SpringDocConfigProperties springDocConfigProperties,
PropertyResolverUtils propertyResolverUtils,
Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers,
Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers,
Optional<JavadocProvider> javadocProvider) {
return new CustomOpenAPIService(openAPI, securityParser, springDocConfigProperties,
propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider);
}
3.Controller使用:
@Tag(name = "tag名称", description = "tag描述")
@ApiSupport(order = 1)
@RestController
public class AuthController {
....
}