如何使用 Jackson 将原始 JSON 反序列化为 Java 对象

Posted

技术标签:

【中文标题】如何使用 Jackson 将原始 JSON 反序列化为 Java 对象【英文标题】:How to deserialize raw JSON to Java object with Jackson 【发布时间】:2021-05-20 04:16:25 【问题描述】:

我有两个 POJO:

@lombok.Value
public class Foo 
  String foo;
  Bar bar;


@lombok.Value
public class Bar 
  String bar;
  String baz;

我希望能够将以下内容反序列化为 Foo 实例:


  "foo": "some foo",
  "bar": " \"bar\": \"some bar\", \"baz\": \"some baz\" "

如果我理解正确,这完全相反@JsonRawValue。在那里,它将 Java 字符串值(这是有效的 JSON 值)转换为 JSON 对象。但在这里,我需要将 JSON 字符串值转换为 Java 对象。 我怀疑我需要编写一个自定义的反序列化器,但我不确定它到底是怎么回事,因为它涉及解析原始 JSON 并将其分配给该字段。也许BeanDeserializerModifier? (我不知道如何使用它。) 我想保持对象不可变 (@Value),但如果它有助于解决问题,我可以放弃此要求。 谢谢。

【问题讨论】:

这能回答你的问题吗? Is it possible to make Jackson serialize a nested object as a string 看看这个answer。如果您将JSON 有效负载作为String 放入另一个JSON 有效负载,则需要对其进行两次反序列化。首先在根级别,然后在转义级别。 这两个问题都是相关的,请检查它们。谢谢。 【参考方案1】:

如果您使用 FooDto 类,请从 DtoClass 中删除此 Bar bar;

或者使用这个

@lombok.Value
public class Foo 
  String foo;
  @JsonIgnore
  Bar bar;

【讨论】:

删除该字段?为什么?我需要这个领域。 像这样从 Dto 类中删除字段 public class FooDot' not Entity class public class Foo' 但在你的情况下使用 @JsonIgnore 注释【参考方案2】:

在@Michał Ziober 提到的this 问题的帮助下,我设法做到了。在这里发布它以供参考,因为让它工作有点棘手(在 JSON 中使用 @ValueCamelCase 属性命名):


  "Foo": "some foo",
  "Bar": " \"bar\": \"some bar\", \"baz\": \"some baz\" "


而实现是:

@Value
@Builder
@JsonDeserialize(builder = Foo.FooBuilder.class)
public class Foo 
    @JsonAlias("Foo") // note this!
    String foo;
    Bar bar;

    @JsonPOJOBuilder(withPrefix = "")
    public static class FooBuilder 
        @JsonAlias("Bar") // note this!
        @JsonDeserialize(using = BarDeserializer.class)
        public FooBuilder bar(Bar bar) 
            this.bar = bar;
            return this;
        
    


@lombok.Value
public class Bar 
  String bar;
  String baz;


public class BarDeserializer extends StdDeserializer<Bar> 
    public BarDeserializer() 
        super(Bar.class);
    

    @Override
    public Bar deserialize(JsonParser p, DeserializationContext ctx) throws IOException 
        return (Bar) ((ObjectMapper) p.getCodec()).readValue(p.getValueAsString(), _valueClass);
    

【讨论】:

以上是关于如何使用 Jackson 将原始 JSON 反序列化为 Java 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Jackson 在对象中包含原始 JSON?

如何在 Jackson 中记录 JSON 反序列化

如何使用 Jackson 反序列化来自 json 对象的对象数组

如何使用jackson(Java)反序列化对象中的json对象?

如何使用 Jackson json 注释枚举字段以进行反序列化

使用 Jackson 将 JSON 反序列化为 ArrayList<POJO>