nic*_*hoe 5 java jackson swagger swagger-codegen openapi-generator
我在组件模式中使用 OpenAPI 3.0 继承,并且我有由 openapi-generator(使用 Jackson)生成的(Java)类。
为什么鉴别器属性在生成的 JSON 中被序列化两次?
这是一个 JHipster API-First 项目,它应该使用 openapi-generator 来生成 Java 模型(带有 Jackson 注释的 POJO)和 API 控制器(与 Spring 的 @Api 注释的接口)。
通过遵循 OpenAPI 3.x 文档/示例,似乎discriminator还必须在properties架构列表中指定所使用的属性。
这样,生成的 Java 类似乎与带有注释的多态类型处理的 Jackson 指南(此处)不同,其中用作鉴别器的属性不能出现在类中。相反,生成的代码还包含此属性作为具有 getter/setter 的类属性。这会导致 JSON 输出两次包含该属性,如下所示。
我还尝试从 OpenAPIproperties列表中删除该属性,而保留完整的discriminator部分;这样生成的代码对应于杰克逊的指导方针,序列化工作得很好。另一方面,我在反序列化过程中遇到错误,因为在目标类中找不到(已删除)属性。
遵循 OpenAPI 3.x 文档指南:
TicketEvent:
type: object
description: A generic event
discriminator:
propertyName: type
required:
- id
- sequenceNumber
- timestamp
- type
properties:
id:
type: integer
format: int64
readOnly: true
sequenceNumber:
type: integer
readOnly: true
timestamp:
type: string
format: date-time
readOnly: true
type:
type: string
readOnly: true
TicketMovedEvent:
description: A ticket move event
allOf:
- $ref: '#/components/schemas/Event'
- type: object
required:
- source
- target
properties:
source:
$ref: '#/components/schemas/Queue'
target:
$ref: '#/components/schemas/Queue'
Run Code Online (Sandbox Code Playgroud)
生成的类:
TicketEvent:
type: object
description: A generic event
discriminator:
propertyName: type
required:
- id
- sequenceNumber
- timestamp
- type
properties:
id:
type: integer
format: int64
readOnly: true
sequenceNumber:
type: integer
readOnly: true
timestamp:
type: string
format: date-time
readOnly: true
type:
type: string
readOnly: true
TicketMovedEvent:
description: A ticket move event
allOf:
- $ref: '#/components/schemas/Event'
- type: object
required:
- source
- target
properties:
source:
$ref: '#/components/schemas/Queue'
target:
$ref: '#/components/schemas/Queue'
Run Code Online (Sandbox Code Playgroud)
JSON 包含两次属性:
{
...
"type": "TicketMovedEvent",
"type": null,
...
}
Run Code Online (Sandbox Code Playgroud)
从properties列表中删除鉴别器属性:
TicketEvent:
type: object
description: A generic event
discriminator:
propertyName: type
required:
- id
- sequenceNumber
- timestamp
properties:
id:
type: integer
format: int64
readOnly: true
sequenceNumber:
type: integer
readOnly: true
timestamp:
type: string
format: date-time
readOnly: true
Run Code Online (Sandbox Code Playgroud)
生成的没有type属性的类:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = TicketMovedEvent.class, name = "TicketMovedEvent")
})
public class TicketEvent {
...
@JsonProperty("type")
private String type;
Run Code Online (Sandbox Code Playgroud)
JSON 现在是正确的:
{
...
"type": "TicketMovedEvent",
...
}
Run Code Online (Sandbox Code Playgroud)
我希望通过遵循 OpenAPI 3.x 指南,生成的类可以正确序列化/反序列化。
(边注)
在反序列化期间,通过使用上述方法,您可能会收到以下错误:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type" (class it.blutec.bludesk.web.api.model.TicketMovedEvent), not marked as ignorable ...
Run Code Online (Sandbox Code Playgroud)
要解决此问题,您需要配置 Jackson ObjectMapper 对象以忽略此类情况。
{
...
"type": "TicketMovedEvent",
"type": null,
...
}
Run Code Online (Sandbox Code Playgroud)
小智 2
我自己刚刚遇到了这个。在 OpenApi 属性列表中不包含鉴别器字段确实可以解决序列化时的双字段问题,同时在反序列化时导致 UnrecognizedPropertyException。经过一番试验,我发现第二个问题可以通过删除生成代码中注释"visible = true"的属性(或将其设置为 false)来解决。@JsonTypeInfo(如果您将构建流程设置为始终从开放 API 规范重新生成代码,那么当然,这不是真正的解决方案)。