gpt4 book ai didi

java - 如何从 Swagger ApiModelProperty 注释生成示例 POJO?

转载 作者:行者123 更新时间:2023-11-30 06:08:21 61 4
gpt4 key购买 nike

我们正在创建一个 REST API,该 API 使用 Swagger 的 @ApiModelProperty 注释进行记录。我正在为 API 编写端到端测试,并且需要为某些请求生成 JSON 正文。假设我需要将以下 JSON 发布到端点:

{ "name": "dan", "age": "33" }

到目前为止,我创建了一个单独的类,其中包含所有必要的属性,并且可以使用 Jackson 将其序列化为 JSON:

@JsonIgnoreProperties(ignoreUnknown = true)
public class MyPostRequest {
private String name;
private String age;
// getters and fluid setters omitted...
public static MyPostRequest getExample() {
return new MyPostRequest().setName("dan").setAge("33");
}
}

但是,我们注意到代码库中已经有一个非常相似的类,它定义了 API 接受的模型。在此模型类中,每个属性的示例值已在 @ApiModelProperty 中定义:

@ApiModel(value = "MyAPIModel")
public class MyAPIModel extends AbstractModel {

@ApiModelProperty(required = true, example = "dan")
private String name;

@ApiModelProperty(required = true, example = "33")
private String age;

}

是否有一种简单的方法来生成填充每个属性的示例值的 MyAPIModel 实例?注意:在转换为 JSON 之前,我需要能够在端到端测试中修改单个属性,以便测试不同的边缘情况。因此,直接生成示例 JSON 是不够的。

本质上,我可以在 MyAPIModel 上(或者在基类 AbstractModel 上更好)编写一个静态方法 getExample() 来返回 Swagger 注释中指定的 MyAPIModel 示例实例吗?

最佳答案

截至本回答时,这似乎不可能。我发现的最接近的可能性是:

  1. io.swagger.converter.ModelConverters:方法 read() 创建 Model 对象,但 example这些模型中的 成员为空。这些示例以字符串形式存在于 properties 成员中(直接取自 APIModelParameter 注释)。

  2. io.swagger.codegen.examples.ExampleGenerator:方法 resolveModelToExample() 获取 ModelConverters.read() 的输出>,并生成一个表示对象及其属性的 Map(同时还解析非字符串属性,例如嵌套模型)。该方法用于序列化为 JSON。不幸的是,resolveModelToExample() 是私有(private)的。如果可以公开访问,则为带注释的 Swagger API 模型类生成模型默认值的代码可能如下所示:

protected <T extends AbstractModel> T getModelExample(Class<T> clazz) {
// Get the swagger model instance including properties list with examples
Map<String,Model> models = ModelConverters.getInstance().read(clazz);
// Parse non-string example values into proper objects, and compile a map of properties representing an example object
ExampleGenerator eg = new ExampleGenerator(models);
Object resolved = eg.resolveModelToExample(clazz.getSimpleName(), null, new HashSet<String>());
if (!(resolved instanceof Map<?,?>)) {
// Model is not an instance of io.swagger.models.ModelImpl, and therefore no example can be resolved
return null;
}
T result = clazz.newInstance();
BeanUtils.populate(result, (Map<?,?>) resolved);
return result;
}
  • 由于在我们的例子中,我们需要的只是 String、boolean 和 int 属性,因此至少有可能以一种疯狂的黑客方式自己解析注释:
  • protected <T extends MyModelBaseClass> T getModelExample(Class<T> clazz) {
    try {
    T result = clazz.newInstance();
    for(Field field : clazz.getDeclaredFields()) {
    if (field.isAnnotationPresent(ApiModelProperty.class)) {
    String exampleValue = field.getAnnotation(ApiModelProperty.class).example();
    if (exampleValue != null) {
    boolean accessible = field.isAccessible();
    field.setAccessible(true);
    setField(result, field, exampleValue);
    field.setAccessible(accessible);
    }
    }
    }
    return result;
    } catch (InstantiationException | IllegalAccessException e) {
    throw new IllegalArgumentException("Could not create model example", e);
    }
    }

    private <T extends MyModelBaseClass> void setField(T model, Field field, String value) throws IllegalArgumentException, IllegalAccessException {
    Class<?> type = field.getType();
    LOGGER.info(type.toString());
    if (String.class.equals(type)) {
    field.set(model, value);
    } else if (Boolean.TYPE.equals(type) || Boolean.class.equals(type)) {
    field.set(model, Boolean.parseBoolean(value));
    } else if (Integer.TYPE.equals(type) || Integer.class.equals(type)) {
    field.set(model, Integer.parseInt(value));
    }
    }

    我稍后可能会在 Github 上提出问题/PR,建议向 Swagger 添加功能。令我感到非常惊讶的是,考虑到我们将示例性模型实例发送到 API 作为测试的用例应该很常见,似乎没有其他人请求此功能。

    关于java - 如何从 Swagger ApiModelProperty 注释生成示例 POJO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50802022/

    61 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com