java - Swagger 注释别名不会生成正确的 OpenAPI
问题描述
我创建了以下别名:
@Retention(RetentionPolicy.RUNTIME)
@Parameter(in = ParameterIn.PATH,
name = "FieldId",
required = true,
extensions = { @Extension(properties = @ExtensionProperty(name = "custom-type",
value = "FieldId")) })
@AnnotationCollector
public @interface MyAnnotator {
}
生成 OpenAPI 定义时,如果我@Parameter
直接在我的资源中使用 ,它可以工作,但如果我使用@MyAnnotator
,它会被忽略。例如:
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{FieldId}")
void create(@Parameter(in = ParameterIn.PATH,
name = "FieldId",
required = true,
extensions = { @Extension(properties = @ExtensionProperty(name = "custom-type",
value = "FieldId")) },
schema = @Schema(type = "string")) final FieldId fieldId)
会产生
post:
parameters:
- name: FieldId
in: path
required: true
schema:
type: string
x-custom-type: FieldId
但做
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{FieldId}")
void create(@MyAnnotator FieldId fieldId)
才不是。怎么来的?
解决方案
请参阅更新以获取有效的解决方案
不幸的是,swagger-core 不支持此功能。@Parameter
注释必须直接放在参数上。
起初,JaxRS Reader 实现尝试@Parameter
像这样查找和解析注释。
io.swagger.v3.oas.annotations.Parameter paramAnnotation = AnnotationsUtils.getAnnotation(io.swagger.v3.oas.annotations.Parameter.class, paramAnnotations[i]);
Type paramType = ParameterProcessor.getParameterType(paramAnnotation, true);
if (paramType == null) {
paramType = type;
} else {
if (!(paramType instanceof Class)) {
paramType = type;
}
}
ResolvedParameter resolvedParameter = getParameters(paramType, Arrays.asList(paramAnnotations[i]), operation, classConsumes, methodConsumes, jsonViewAnnotation);
AnnotationUtils 没有深入
public static <T> T getAnnotation(Class<T> cls, Annotation... annotations) {
if (annotations == null) {
return null;
}
for (Annotation annotation : annotations) {
if (cls.isAssignableFrom(annotation.getClass())) {
return (T)annotation;
}
}
return null;
}
最后getParameters(...)
方法更严格。它检查注释的类型是否与所需的类型完全相同。
for (Annotation annotation : annotations) {
if (annotation instanceof QueryParam) {
QueryParam param = (QueryParam) annotation;
// ...
} else if (annotation instanceof PathParam) {
PathParam param = (PathParam) annotation;
// ...
} else if (annotation instanceof MatrixParam) {
MatrixParam param = (MatrixParam) annotation;
// ...
}
// ... and so on
}
但隧道尽头有一些光亮。您可以创建一个自定义的 ParameterExtension 服务实现OpenAPIExtension
并且您可以处理这些自定义注释。
更新:工作解决方案
正如我之前提到的,允许创建自定义 ParameterExtension 服务。我做了一个最小的参数解析器扩展,它扩展了DefaultParameterExtension
.
基本概念
所有参数模板都需要创建为自定义注释,如下所示:
@Retention(RetentionPolicy.RUNTIME)
@Parameter(in = ParameterIn.PATH,
name = "FieldId",
required = true,
extensions = {@Extension(properties = @ExtensionProperty(name = "custom-type",
value = "FieldId"))})
public @interface MyAnnotator {
}
扩展的 ParameterExtension 读取@ParameterAlias
具有强制属性的注释。
@Path("/v1")
@Tags(@Tag(name = "test", description = ""))
public class FooResource {
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{FieldId}")
@Operation(operationId = "modifyFoo", summary = "Modifies a Foo entity")
public void modify(@ParameterAlias(MyAnnotator.class) final FieldId fieldId) {
}
}
最后扩展扩展ParameterAliasExtension
处理@ParameterAliasExtension
public class ParameterAliasExtension extends DefaultParameterExtension {
@Override
public ResolvedParameter extractParameters(List<Annotation> annotations,
Type type,
Set<Type> typesToSkip,
Components components,
javax.ws.rs.Consumes classConsumes,
javax.ws.rs.Consumes methodConsumes,
boolean includeRequestBody,
JsonView jsonViewAnnotation,
Iterator<OpenAPIExtension> chain) {
List<Annotation> extendedAnnotations = null;
if (null != annotations) {
extendedAnnotations = new ArrayList<>(annotations);
ParameterAlias alias = AnnotationsUtils.getAnnotation(ParameterAlias.class, annotations.toArray(new Annotation[0]));
if (null != alias) {
Parameter aliasParameter = AnnotationsUtils.getAnnotation(Parameter.class, alias.value().getDeclaredAnnotations());
if (null != aliasParameter) {
extendedAnnotations.add(aliasParameter);
}
}
}
return super.extractParameters(extendedAnnotations == null ? annotations : extendedAnnotations,
type,
typesToSkip,
components,
classConsumes,
methodConsumes,
includeRequestBody,
jsonViewAnnotation,
chain);
}
}
此示例在我的 GitHub 存储库中可用:https ://github.com/zforgo/stackoverflow/tree/master/openapi-alias
推荐阅读
- python - Kivy 不显示操作栏
- ios - UIImagePickerControllerEditedImage 以黑色背景保存图像
- java - 无法从java中的控制台获取输入
- spring-boot - 具有多个数据库和 application.yml 的 JPA
- python - 使用 MyClass(object) 出错了吗?
- c++ - bsoncxx::stdx::optional 和 mongocxx::stdx::optional
- c# - 如何在 C# 中将 Linq 计数与 group by 一起使用
- javascript - webview js界面不能使用原型
- scala - Spark Dataframe - 将特定行推到数据框中的最后一个
- php - 按价格排序并排序订单号 opencart