使用 Jackson 反序列化(在未知属性上失败)不会忽略鉴别器 属性(使用 SwaggerCodegen 创建的 DTO)
Deserializing with Jackson (fail on unknown properties) does not ignore discriminator property (DTO's created with SwaggerCodegen)
编辑:
我发现了问题:我必须找到一种方法让 swagger Codegen 在生成 java [=69 时删除 "visible = true" 部分=].如果我手动删除它,它就会工作。问题是 classes 在编译时生成并且修改将被覆盖。
仍然需要帮助!
初始post:
我有以下内容:
具有列表的接待实体class。 Checkpoint 是基础class,但它只会包含子class,如Checkpoint1、Checkpoint2 等
一个 ReceptionCotroller,它有一个由“/receptions”映射的 HTTP POST 方法。
DTO classes 用于接收和检查点(检查点基础 class、检查点 1、检查点 2 等)使用 Swagger CodeGen openapi 3.0.2 生成。使用 yml 文件。检查点 DTO 有一个名为 "dtype" 的鉴别器字段(在 yml 文件中),因此当将 JSON 反序列化为检查点时,它知道它指的是什么 subclass 。
问题是当我添加 属性: spring.jackson.deserialization.fail-on-unknown-properties = true 时,它无法识别 "dtype" 属性 并失败.我希望应用程序在遇到未知属性时失败,但要忽略 "dtype".
我试图在检查点 DTO 中添加一个 dtype 字段(在鉴别器定义旁边),但是 JSON 作为响应 returns 有 2 个 dtype 字段(一个带有鉴别器值,一个为空)。
yml 文件中的接收和检查点:
Reception:
description: description1
type: object
properties:
id:
type: integer
format: int64
description: Id of the reception.
checkpoints:
type: array
items:
oneOf:
- $ref: '#/components/schemas/Checkpoint1'
- $ref: '#/components/schemas/Checkpoint2'
discriminator:
propertyName: dtype
$ref: '#/components/schemas/Checkpoint'
description: List of checkpoints attached to this reception.
Checkpoint:
description: Checkpoint entity.
type: object
properties:
checkpointId:
type: string
description: description1.
required:
- checkpointId
- dtype
discriminator:
propertyName: dtype
生成检查点 DTO class:
@ApiModel(description = "Checkpoint entity.")
@Validated
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "dtype", visible = true )
@JsonSubTypes({
@JsonSubTypes.Type(value = Checkpoint1.class, name = "Checkpoint1"),
@JsonSubTypes.Type(value = Checkpoint2.class, name = "Checkpoint2")
})
public class Checkpoint {
@JsonProperty("dtype")
private String dtype = null;
@JsonProperty("checkpointId")
private String checkpointId = null;
(.....)
Json 作为请求正文发送:
{
"id": 123,
"checkpoints": [
{
"dtype": "Checkpoint1",
"checkpointId": "Checkpoint1"
}
}
它说它不识别dtype字段。我希望它创建适当的检查点对象,但忽略了检查点 DTO 在生成的 class 中实际上不包含 dtype 字段。我不希望它忽略其他未知属性。例如:如果我在 JSON 中添加另一个 "fooBar" 字段,我希望它失败。
希望所提供的信息能够理解我的问题所在。如果没有,我可以提供进一步的信息。
非常感谢!!
PS:请忽略最终的语法错误或拼写错误,代码可以正常工作并正确编译,但我不知道如何仅忽略鉴别器 (dtype) 属性。
有两种方法可以完成此操作。
第一:
如果允许更改自动生成的 java 代码,则可以将注释 @JsonIgnoreProperties(value = ["dtype"]) 添加到所有 classes 具有如下所示的鉴别器字段。
@JsonIgnoreProperties(value = ["dtype"])
public class Checkpoint {
//your properties here
}
示例实现:
这个问题有一个示例实现
第二个:
如果不允许您编辑自动生成的 java 代码,您可以使用 Jackson Mixins 来忽略特定的不需要的字段。
@JsonIgnoreProperties(value = ["dtype"])
public abstract class CheckpointMixin {}
并在您的对象映射器中为目标 class 注册此 mixin,如下所示:
mapper.addMixIn(Checkpoint::class.java, CheckpointMixin::class.java)
我在 kotlin 中试用了它,它按预期工作。请忽略任何语法错误。
编辑:
我发现了问题:我必须找到一种方法让 swagger Codegen 在生成 java [=69 时删除 "visible = true" 部分=].如果我手动删除它,它就会工作。问题是 classes 在编译时生成并且修改将被覆盖。
仍然需要帮助!
初始post:
我有以下内容:
具有列表的接待实体class。 Checkpoint 是基础class,但它只会包含子class,如Checkpoint1、Checkpoint2 等
一个 ReceptionCotroller,它有一个由“/receptions”映射的 HTTP POST 方法。
DTO classes 用于接收和检查点(检查点基础 class、检查点 1、检查点 2 等)使用 Swagger CodeGen openapi 3.0.2 生成。使用 yml 文件。检查点 DTO 有一个名为 "dtype" 的鉴别器字段(在 yml 文件中),因此当将 JSON 反序列化为检查点时,它知道它指的是什么 subclass 。
问题是当我添加 属性: spring.jackson.deserialization.fail-on-unknown-properties = true 时,它无法识别 "dtype" 属性 并失败.我希望应用程序在遇到未知属性时失败,但要忽略 "dtype".
我试图在检查点 DTO 中添加一个 dtype 字段(在鉴别器定义旁边),但是 JSON 作为响应 returns 有 2 个 dtype 字段(一个带有鉴别器值,一个为空)。
yml 文件中的接收和检查点:
Reception:
description: description1
type: object
properties:
id:
type: integer
format: int64
description: Id of the reception.
checkpoints:
type: array
items:
oneOf:
- $ref: '#/components/schemas/Checkpoint1'
- $ref: '#/components/schemas/Checkpoint2'
discriminator:
propertyName: dtype
$ref: '#/components/schemas/Checkpoint'
description: List of checkpoints attached to this reception.
Checkpoint:
description: Checkpoint entity.
type: object
properties:
checkpointId:
type: string
description: description1.
required:
- checkpointId
- dtype
discriminator:
propertyName: dtype
生成检查点 DTO class:
@ApiModel(description = "Checkpoint entity.")
@Validated
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "dtype", visible = true )
@JsonSubTypes({
@JsonSubTypes.Type(value = Checkpoint1.class, name = "Checkpoint1"),
@JsonSubTypes.Type(value = Checkpoint2.class, name = "Checkpoint2")
})
public class Checkpoint {
@JsonProperty("dtype")
private String dtype = null;
@JsonProperty("checkpointId")
private String checkpointId = null;
(.....)
Json 作为请求正文发送:
{
"id": 123,
"checkpoints": [
{
"dtype": "Checkpoint1",
"checkpointId": "Checkpoint1"
}
}
它说它不识别dtype字段。我希望它创建适当的检查点对象,但忽略了检查点 DTO 在生成的 class 中实际上不包含 dtype 字段。我不希望它忽略其他未知属性。例如:如果我在 JSON 中添加另一个 "fooBar" 字段,我希望它失败。
希望所提供的信息能够理解我的问题所在。如果没有,我可以提供进一步的信息。
非常感谢!! PS:请忽略最终的语法错误或拼写错误,代码可以正常工作并正确编译,但我不知道如何仅忽略鉴别器 (dtype) 属性。
有两种方法可以完成此操作。
第一:
如果允许更改自动生成的 java 代码,则可以将注释 @JsonIgnoreProperties(value = ["dtype"]) 添加到所有 classes 具有如下所示的鉴别器字段。
@JsonIgnoreProperties(value = ["dtype"])
public class Checkpoint {
//your properties here
}
示例实现:
第二个:
如果不允许您编辑自动生成的 java 代码,您可以使用 Jackson Mixins 来忽略特定的不需要的字段。
@JsonIgnoreProperties(value = ["dtype"])
public abstract class CheckpointMixin {}
并在您的对象映射器中为目标 class 注册此 mixin,如下所示:
mapper.addMixIn(Checkpoint::class.java, CheckpointMixin::class.java)
我在 kotlin 中试用了它,它按预期工作。请忽略任何语法错误。