我创建了以下别名:
@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)
没有。怎么会来?
答案 0 :(得分:3)
不幸的是,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
}
但是隧道尽头有一些光线。您可以创建实现OpenAPIExtension
的自定义ParameterExtension服务,并可以处理这些自定义注释。
正如我在创建自定义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