java - 如何手动记录 JAX-RS 参数的 Swagger 数据模型?
问题描述
语境
假设我在 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;
}
}
注意:在实践中,我使用Immutables来生成它,但为了简单起见,我在这里展示了一个POJO 。
为了记录GET
响应的模型,即使返回类型是Response
,我也可以参考 中的类@ApiOperation
:
@GET
@ApiOperation(response = Person.class)
public Response getPerson() {
return Response.ok(new Person("Julien", 28)).build();
}
基于此,Swagger 将正确记录这一点:
模型:
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
将正文键入为 plain 的请求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 现在用JsonNode
Java 对象的属性记录部分更新的模型:
模型:
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 }
我想在我的代码中指定模型是 like Person
,以便 Swagger UI 中给出的示例更相关。我确实尝试过@ApiImplicitParams
:
@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
自己。@ApiImplicitParams
提及的文档:
虽然ApiParam绑定到 JAX-RS 参数、方法或字段,但这允许您以微调的方式手动定义参数。这是使用 Servlet 或其他非 JAX-RS 环境时定义参数的唯一方法。
由于我使用的是 JAX-RS,这可能意味着我不能使用@ApiImplicitParams
,但@ApiParam
不提供任何东西来覆盖该类。
如何手动指定 Swagger 自动检测到的 JAX-RS 参数的数据模型?
解决方案
我走在正确的轨道上@ApiImplicitParam
,我想我现在按照我想要的方式工作了:
@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)
。
使用上面的代码,文档看起来完全符合我的要求,并且代码继续正常运行。
感谢大家的帮助!
推荐阅读
- eclipse-rcp - 如何使用 java 读取 Eclipse rcp 应用程序中的 .xml 文件路径?
- python-3.x - 熊猫中`header = None`和`header = 0`之间的区别
- unity3d - 有谁知道为什么我的相机尺寸与默认的网格尺寸不一致???
- r - 如何使用 R 代码在现有 png 图像的右上角添加色标?
- sql - 无法使用 SID 连接到 SQL*Plus
- python - 在执行一些以前有效的代码后,Python 在出现“分段错误(核心转储)”错误消息的第一个实例后停止工作
- linux - 在 Linux 中安装 rapid 时出错
- c# - 将 Json 字符串发布到 WebApi 总是以空参数结束
- scala - 如何获取scala列表中重复对的索引
- twitter-bootstrap - 如何根据输入组调整边框?