歧视器属性的双重序列化之谜:深入解析解决方案
2024-03-07 02:24:30
歧视器属性的双重序列化之谜
导言
在 OpenAPI 3.0 的组件模式中使用继承时,歧视器属性可能会意外地被序列化两次。了解问题的原因并找到解决方法至关重要。本文将深入探讨这个问题,并提供一个清晰的解决方案。
背景
在 JHipster API 优先项目中,使用 openapi-generator 来生成 Java 代码。根据 OpenAPI 3.x 规范,作为“歧视器”的属性也必须在模式的“属性”列表中指定。
问题
然而,生成的 Java 类没有遵循 Jackson 多态类型处理注解指南。生成的代码包含一个类属性,用于歧视器属性,带有 getter/setter。这导致 JSON 输出包含该属性两次。
原因
原因在于生成的代码不符合 Jackson 的指南,其中歧视器的属性不应存在于类中。相反,它将该属性作为类属性。
尝试的解决方案
尝试从 OpenAPI“属性”列表中删除歧视器属性,但反序列化过程失败,因为目标类中找不到(已删除的)属性。
解决方案
通过仔细检查 OpenAPI 3.x 文档,我们发现了一个解决方法。要防止歧视器属性的双重序列化,只需从 OpenAPI 的“属性”列表中删除该属性即可。这样,生成的 Java 类将符合 Jackson 的指南,并且序列化/反序列化将正常工作。
示例
为了说明这一点,考虑以下 OpenAPI 模式:
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'
生成的 Java 类将如下所示:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = TicketMovedEvent.class, name = "TicketMovedEvent")
})
public class TicketEvent {
...
// "type" 属性已从类中删除
})
JSON 输出将是正确的:
{
...
"type": "TicketMovedEvent",
...
}
结论
遵循 OpenAPI 3.x 规范可以生成可以正确序列化/反序列化的类。通过从 OpenAPI 的“属性”列表中删除歧视器属性,我们可以防止歧视器属性的双重序列化并确保正确的数据处理。
常见问题解答
-
歧视器属性是什么?
歧视器属性是一个用于区分继承类中子类型的属性。 -
为什么歧视器属性有时会序列化两次?
在 Java 中,根据 Jackson 的指南,歧视器属性不应存在于类中。然而,openapi-generator 生成的代码包含一个歧视器属性的类属性,导致双重序列化。 -
如何解决歧视器属性的双重序列化问题?
从 OpenAPI 的“属性”列表中删除歧视器属性。 -
如果我从“属性”列表中删除了歧视器属性,反序列化会发生什么?
反序列化将失败,因为目标类中找不到(已删除的)属性。 -
在解决歧视器属性的双重序列化问题时,我应该注意哪些其他事项?
确保生成的类符合 Jackson 多态类型处理注解指南,并配置 ObjectMapper 对象以忽略未知属性。