Java 为什么鉴别器属性被序列化两次?
我在组件模式中使用OpenAPI3.0继承,我有OpenAPI生成器(使用Jackson)生成的(Java)类 为什么鉴别器属性在结果JSON中序列化两次 这是JHipster API的第一个项目,应该使用openapi生成器生成Java模型(带有Jackson注释的POJO)和API控制器(带有Spring的@API注释的接口) 通过遵循OpenAPI 3.x文档/示例,似乎还必须在模式的Java 为什么鉴别器属性被序列化两次?,java,jackson,swagger,swagger-codegen,openapi-generator,Java,Jackson,Swagger,Swagger Codegen,Openapi Generator,我在组件模式中使用OpenAPI3.0继承,我有OpenAPI生成器(使用Jackson)生成的(Java)类 为什么鉴别器属性在结果JSON中序列化两次 这是JHipster API的第一个项目,应该使用openapi生成器生成Java模型(带有Jackson注释的POJO)和API控制器(带有Spring的@API注释的接口) 通过遵循OpenAPI 3.x文档/示例,似乎还必须在模式的properties列表中指定用作鉴别器的属性 通过这种方式,生成的Java类似乎不同于Jackson关于
properties
列表中指定用作鉴别器的属性
通过这种方式,生成的Java类似乎不同于Jackson关于使用annotations()处理多态类型的指导原则,其中用作鉴别器的属性不能出现在类中。相反,生成的代码还将此属性作为类属性包含在getter/setter中。这会导致JSON输出包含属性两次,如下所示
我还尝试从OpenAPIproperties
列表中删除属性,保留鉴别器部分的完整性;通过这种方式,生成的代码符合Jackson的准则,序列化工作正常。另一方面,我在反序列化过程中遇到一个错误,因为在目标类中找不到(removed)属性
遵循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'
生成的类:
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”,visible=true)
@JsonSubTypes({
@JsonSubTypes.Type(value=TicketMovedEvent.class,name=“TicketMovedEvent”)
})
公共类票务{
...
@JsonProperty(“类型”)
私有字符串类型;
JSON包含两次属性:
{
...
"type": "TicketMovedEvent",
"type": null,
...
}
从属性
列表中删除鉴别器属性:
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
生成的类没有类型
属性:
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”,visible=true)
@JsonSubTypes({
@JsonSubTypes.Type(value=TicketMovedEvent.class,name=“TicketMovedEvent”)
})
公共类票务{
...
//现在缺少“type”属性
})
JSON现在是正确的:
{
...
"type": "TicketMovedEvent",
...
}
我希望,通过遵循OpenAPI3.x准则,生成的类能够正确地序列化/反序列化
(旁注)
在反序列化过程中,通过使用上述方法,可能会出现以下错误:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type" (class it.blutec.bludesk.web.api.model.TicketMovedEvent), not marked as ignorable ...
要解决此问题,需要将Jackson ObjectMapper对象配置为忽略此类情况
ObjectMapper om=new ObjectMapper().configure(反序列化功能.FAIL_ON_UNKNOWN_属性,false)
我自己也遇到了这个问题。在OpenApi属性列表中不包含鉴别器字段确实解决了序列化时的双字段问题,同时在反序列化时导致无法识别的属性异常。
经过一些尝试和错误,我发现第二个问题可以通过删除生成代码中@JsonTypeInfo
注释的“visible=true”
属性(或将其设置为false)来解决。(如果您的构建过程设置总是从openapi规范重新生成代码,那么当然,这不是一个真正的解决方案)。我相信我解决了这个问题,应该在openapi generator 4.3发行版中发布。请随意查看它(由于该PR,支持之一也应该得到极大改进).我遇到了同样的问题。问题在于生成的模型类上的@JsonTypeInfo
注释
其生成为-
@JsonTypeInfo(... include = JsonTypeInfo.As.PROPERTY ...)
这将在模型中添加一个额外的属性
如果我在生成的代码中将其更改为-
@JsonTypeInfo(... include = JsonTypeInfo.As.EXISTING_PROPERTY ...)
它使用模型中已经存在的属性,并且一切正常
但是,当我重新生成代码时,这个更改当然会丢失。
如果有人找到了一个永久的解决方案,那就太好了。在openapi生成器存储库中打开一个问题@Helen Thank:我遇到了一个类似的问题(虽然我没有使用openapi,只是简单的Jackson,我完全控制了源代码)。如果我没记错的话,修复方法是使用JsonTypeInfo.As.EXISTING_属性
而不是JsonTypeInfo.As.PROPERTY
@cassiomolin我已经尝试用JsonTypeInfo.As.EXISTING_属性
手动重写生成的类,这就是“鉴别器”在JSON中只出现一次,但它有null
值。我认为这与为Spring生成的代码有关,实际上我正试图在openapi生成器repo中找到一些线索。谢谢。是的,问题取决于生成过程。手动编辑生成的类可以是一种解决方法,但我希望是这样最终修复。如果你想跟踪这个问题,这里是GitHub链接:我已经尝试了4.3.0-SNAPSHOT(在我的机器上构建),带有“spring”目标,但discriminator属性仍在生成的类中。我的建议是避免在类中生成discriminator属性,因为由于(Jackson)的原因,此信息已经存在JsonTypeInfo
annotation。我为此打开了一个问题:没错。一年前,我打开了一个,如果你想跟踪这个问题的话。我看到有人合并了一个PR-它将类型信息批注更改为现有属性。是的,但这似乎不适用于此问题。请检查我的。无论如何,我会再试一次在中。(我在上面的评论中支持现有的_属性
解决方案,因为我忘了它对我不起作用)