如何使用 Jackson 将原始 JSON 反序列化为 Java 对象
How to deserialize raw JSON to Java object with Jackson
我有两个 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
),但如果它有助于解决问题,我可以放弃此要求。
谢谢。
如果您使用 FooDto class 从 DtoClass
中删除这个 Bar bar;
或使用这个
@lombok.Value
public class Foo {
String foo;
@JsonIgnore
Bar bar;
}
在@Michał Ziober 提到的 问题的帮助下,我设法做到了。将它张贴在这里以供参考,因为让它工作有点棘手(@Value
和 CamelCase
属性 在 JSON 中命名):
{
"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);
}
}
我有两个 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
),但如果它有助于解决问题,我可以放弃此要求。
谢谢。
如果您使用 FooDto class 从 DtoClass
中删除这个Bar bar;
或使用这个
@lombok.Value
public class Foo {
String foo;
@JsonIgnore
Bar bar;
}
在@Michał Ziober 提到的 @Value
和 CamelCase
属性 在 JSON 中命名):
{
"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);
}
}