首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swagger注释别名不会生成正确的OpenAPI

Swagger注释别名不会生成正确的OpenAPI
EN

Stack Overflow用户
提问于 2019-12-25 02:18:05
回答 1查看 663关注 0票数 1

我创建了以下别名:

代码语言:javascript
复制
@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,它会被忽略。举个例子:

代码语言:javascript
复制
@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)

将生成

代码语言:javascript
复制
post:
  parameters:
  - name: FieldId
    in: path
    required: true
    schema:
      type: string
    x-custom-type: FieldId

但是在做

代码语言:javascript
复制
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{FieldId}")
void create(@MyAnnotator FieldId fieldId)

不会。怎么会这样?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-25 04:59:51

请参阅工作解决方案的更新

不幸的是,swagger-core不支持这个特性。@Parameter批注必须直接放在参数上。

首先,JaxRS阅读器实现试图像这样查找和解析@Parameter注释。

代码语言:javascript
复制
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不会更深入

代码语言:javascript
复制
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(...)方法更加严格。它检查注解的类型是否与所需的类型完全相同。

代码语言:javascript
复制
    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
    }

但在隧道的尽头也有一些曙光。您可以创建实现OpenAPIExtension的自定义ParameterExtension服务,并且可以处理这些自定义批注。

更新:工作解决方案

正如我在前面提到的,允许创建自定义ParameterExtension服务。我做了一个扩展DefaultParameterExtension的最小参数解析器扩展。

基本概念

所有参数模板都需要创建为自定义注释,如下所示:

代码语言:javascript
复制
@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注释。

代码语言:javascript
复制
@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

代码语言:javascript
复制
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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59472239

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档