【问题标题】:Jackson mapper skip class name (deserialization issue)Jackson 映射器跳过类名(反序列化问题)
【发布时间】:2020-08-27 08:55:54
【问题描述】:

我有这个示例类:

@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
public class ExampleClass implements Serializable {
    private String name;
    private String color;
}

这个类序列化为:

{
    "ExampleClass":{
        "name":"This is some name",
        "color":"This is some color"
}}

这是预期的行为,我不应该改变它。 但我首先收到的是这个 json 文件:

{
    "name":"This is some name",
    "color":"This is some color"
}

我需要将它映射到我的 ExampleClass,通常你会这样做:

ExampleClass example = new ObjectMapper().readValue(jsonFile, ExampleClass.class);

但由于我已经指定了带有注释 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) 的类,它试图将接收到的 json 中的“name”字段映射到“ExampleClass”和它抛出一个错误:

无法将类型 id 'name' 解析为 com.example.package.dto.ExampleClass: 已知类型 ID = [示例类]

我知道如果我删除 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) 或者我将其更改为 use = JsonTypeInfo.Id.NONE,反序列化将起作用,但随后序列化的 json 结束正在改变,所以我不能这样做。

我也知道,如果我想添加自定义反序列化器,我还需要添加自定义序列化器,因为 @JsonTypeInfo 注释使杰克逊忽略您在注释中指定的任何反序列化器。但我真的很想避免这种情况,因为实际的类有很多字段,而且自定义映射类看起来很丑。

我如何告诉杰克逊跳过“ExampleClass”字段并将其映射到它的内部字段,或者指定不同的字段?

我用的是fasterxml.jackson,没有codehaus。

【问题讨论】:

    标签: java spring spring-boot jackson fasterxml


    【解决方案1】:

    有趣的是,当我写下我的问题时,我想出了解决方案,只需要实施它并尝试一下,它就完美地运行了!

    我是这样做的:

    @Getter
    @Setter
    @EqualsAndHashCode
    @NoArgsConstructor
    @AllArgsConstructor
    // no more @JsonTypeInfo here
    public class ExampleClass implements Serializable {
        private String name;
        private String color;
    }
    

    我从 ExampleClass 中删除了 @JsonTypeInfo,因为这个类将用于将接收到的 json 反序列化为它。 然后我创建了第二个“包装器”类,我将使用它来序列化数据:

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
    public class ExampleClassWrapper extends ExampleClass {
        public ExampleClassWrapper(ExampleClass ex) {
            super(ex.getName(), ex.getColor());
        } 
    

    现在,当 json 出现时,我可以在一行中毫无错误地读取它:

    ExampleClass example = new ObjectMapper().readValue(jsonFile, ExampleClass.class);
    

    当我需要序列化这些数据时(例如将其作为请求发送),我只需发送 ExampleClassWrapper:

    ExampleClassWrapper wrapper = new ExampleClassWrapper(example);
    exampleRestService.sendExampleRequest(wrapper);
    

    如果您认为有更好的方法来解决这个问题,请随时纠正我。

    附:为在 stackoverflow 中写问题的调试鸭欢呼

    【讨论】:

    • 不,这对别人有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 2021-12-16
    • 2011-06-28
    • 2018-02-28
    • 2018-10-26
    • 2019-01-19
    相关资源
    最近更新 更多