当前位置: 首页 > 知识库问答 >
问题:

如何手动记录JAX-RS参数的Swagger数据模型?

孟哲
2023-03-14

假设我有一个简单的Java数据类:

public class Person {
    private final String name;
    private final int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    int String getAge() {
        return age;
    }
}

注意:在实践中,我使用不可变来生成这个,但是为了简单起见,我在这里显示了一个POJO。

要记录GET响应的模型,即使返回类型是响应,我也可以引用@Api操作中的类:

@GET
@ApiOperation(response = Person.class)
public Response getPerson() {
    return Response.ok(new Person("Julien", 28)).build();
}

基于此,斯威格将正确记录以下内容:

型号:

Person {
  name (string),
  age (number)
}

示例值:

{
  "name": "string",
  "age": 0
}

为了记录POST主体的模型,我直接在代码中使用类,Swagger找到它并根据需要记录它:

@POST
@ApiOperation(response = Person.class)
public Response addPerson(Person newPerson) {
    return Response.ok(store.insert(newPerson)).build();
}

我也想支持部分更新。我不能使用POJO本身,因为POJO中的所有字段都是强制性的,当无效的JSON被发送到例如POST方法时,我依靠它来获得安全检查和清除错误消息。

在我的实际用例中,我的数据模型包含映射。我希望用户能够在更新中指定某个键,并将该值设置为null,以从现有映射中删除元素。

我选择支持PATCH请求,其中正文被键入为普通的JsonNode。这允许我的服务器接收任何JSON,我可以根据自己的意愿应用更新。

@PATCH
@Path("/{name}")
@ApiOperation(response = Person.class)
public Response updatePerson(@PathParam("name") String name, JsonNode update) {
    return Response.ok(store.update(name, update)).build();
}

我对结果很满意,除了Swagger现在用JsonNodeJava对象的属性记录了部分更新的模型:

型号:

JsonNode {
  array (boolean, optional),
  null (boolean, optional),
  number (boolean, optional),
  float (boolean, optional),
  pojo (boolean, optional),
  valueNode (boolean, optional),
  containerNode (boolean, optional),
  object (boolean, optional),
  missingNode (boolean, optional),
  nodeType (string, optional) = ['ARRAY', 'BINARY', 'BOOLEAN', 'MISSING', 'NULL', 'NUMBER', 'OBJECT', 'POJO', 'STRING'],
  integralNumber (boolean, optional),
  floatingPointNumber (boolean, optional),
  short (boolean, optional),
  int (boolean, optional),
  long (boolean, optional),
  double (boolean, optional),
  bigDecimal (boolean, optional),
  bigInteger (boolean, optional),
  textual (boolean, optional),
  boolean (boolean, optional),
  binary (boolean, optional)
}

示例值:

{
  "array": true,
  "null": true,
  "number": true,
  "float": true,
  "pojo": true,
  "valueNode": true,
  "containerNode": true,
  "object": true,
  "missingNode": true,
  "nodeType": "ARRAY",
  "integralNumber": true,
  "floatingPointNumber": true,
  "short": true,
  "int": true,
  "long": true,
  "double": true,
  "bigDecimal": true,
  "bigInteger": true,
  "textual": true,
  "boolean": true,
  "binary": true
}

我想在我的代码中指定模型类似于Person,以便在Swagger UI中给出的示例更加相关。我确实尝试了@apimplicitparams

@PATCH
@Path("/{name}")
@ApiOperation(response = Person.class)
@ApiImplicitParams({
  @ApiImplicitParam(name = "update", dataTypeClass = Person.class)
})
public Response updatePerson(@PathParam("name") String name, JsonNode update) {
    return Response.ok(store.update(name, update)).build();
}

这没有任何区别。Swagger仍然记录JsonNode本身。留档中提到:

虽然ApiParam绑定到JAX-RS参数、方法或字段,但这允许您以微调的方式手动定义参数。这是使用servlet或其他非JAX-RS环境时定义参数的唯一方法。

由于我使用的是JAX-RS,这可能意味着我不能使用@apimplicitparams,但是@apipparam不提供任何重写类的内容。

如何手动指定Swagger自动检测到的JAX-RS参数的数据模型?

共有2个答案

戚承业
2023-03-14

我在正确的轨道上使用了@ApiInphityParam,我想我已经按照我想要的方式工作了,现在:

@PATCH
@Path("/{name}")
@ApiOperation(response = Person.class)
@ApiImplicitParams({
  @ApiImplicitParam(paramType = "body", dataTypeClass = ExchangeConfiguration.class)
})
public Response updatePerson(@PathParam("name") String name, @ApiParam(hidden = true) JsonNode update) {
    return Response.ok(store.update(name, update)).build();
}

配置名称不是强制性的,但似乎需要paramType。使用paramType=“body”可以使Swagger正确地记录隐式参数。这将导致尸体被记录两次;我们可以使用@ApiParam(hidden=true)隐藏使用错误模型自动生成的版本。

使用上面的代码,文档看起来完全符合我的要求,代码继续正确运行。

感谢所有的帮助!

卫嘉佑
2023-03-14

为了更好地理解@apimplicitparams,添加此答案以使其具有某种通用性。

您必须使用@ApiInpositalParams包装参数,因为您希望将其保存在留档中。@ApiInpositalParam有许多不太明显的好处,例如传入额外的头参数,而不将其添加为方法参数或你的箱子把参数包起来,这样它们就有意义了。

对于您的问题,您必须使用@apimplicitparam以及paramType=“body”来更改正文,同样,如果您希望更改标头,则必须使用paramType=“head”

您还可以使用属性required=true/false控制@apimplicitparam中的必填字段。

如前所述,您可以传递一个参数,而不必在方法param中使用它,您可以使用属性value=“required value”控制它的值。

您还可以使用逗号分隔的值控制@apimplicitparam中的允许值。例如,allowableValues=“无缓存,无存储”

 类似资料:
  • 如何配置swaggerui来为具有集合输入参数的JAX-RS资源显示正确的参数datatype? 下面是一个示例groovy JAX-RS资源。其输入类型为 在swagger UI中,我看到填充了空类型的列表,而不是。它对输出参数工作得很好。使用注释,我可以指定响应类型。

  • 问题内容: 我正在尝试使用HttpServletRequest从发布的表单中检索传递给jax- rs的一些参数。但是,我的请求对象始终为我的参数返回空值。我不是要这样做吗?我已经在下面发布了代码,并发送了示例请求。 这是我的服务: 请求示例: 问题答案:

  • 有什么方法可以记录下面的查询吗? 其中查询参数名称是动态的,将从客户端接收。 我正在使用最新的Swagger API。

  • 尝试使用Mockito为下面的代码编写单元测试,但我遇到了错误使用方法的异常。结果不为空,已验证,也进入循环。 这是我所写的: 例外情况:

  • 问题内容: 使用JAX-RS和(java8)时出现问题。 我想使用JSON将这样的对象传递到JAX-RS方法中: 我得到的异常是: :没有合适的构造找到型[简单的类型,类在[来源不能实例从JSON对象(需要添加/启用类型信息)::] ; 行:2,列:3] 如何创建某种将json-dates映射到的拦截器?我尝试实现a ,但是如果is是另一个类中的 字段 ,则我必须为每个持有a的类编写一个(据我所知

  • 使用JAX-RS和(java8)时出现问题。 我想使用JSON将这样一个对象传递到JAX-RS方法中: 我得到的例外是: