Jackson:映射嵌套对象
Posted
技术标签:
【中文标题】Jackson:映射嵌套对象【英文标题】:Jackson : map nested object 【发布时间】:2018-03-17 02:45:27 【问题描述】:使用杰克逊,我想知道是否可以将 json 映射到 Java,其中嵌套的对象与 json 结构不同。
这是我想做的一个例子。
json:
a = "someValue",
b = "someValue",
c = "someValue"
Java:
public class AnObject
@JsonProperty("a")
private String value;
//Nested object
private SomeObject;
public class SomeObject
@JsonProperty("b")
private String value1;
@JsonProperry("c")
private String value2;
有可能吗?
【问题讨论】:
无法使用注解,但您可以编写自己的反序列化器,您可以在其中像 Map 一样管理 Json 并自己填充字段到 pojo。 fasterxml.github.io/jackson-databind/javadoc/2.3.0/com/… @DmytroDovzhenko 提醒你,这确实是可能的,看我的回答 这不是有效的 JSON。 这不是有效的 Java。 【参考方案1】:首先,这是一个 JSON 对象。
这是object literal。
其次,这不是一个有效的格式化对象字面量。 正确的是这样的:
"a" : "someValue", "b": "someValue", "c": "someValue"
接下来,正如 cmets 中所说,您必须定义自己的反序列化器。
主要:
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException
String json = "\"a\" : \"someValue\",\"b\" : \"someValue\",\"c\" : \"someValue\"";
final ObjectMapper om =
new ObjectMapper();//
om.registerSubtypes(AnObject.class);
SimpleModule module = new SimpleModule();
module.addDeserializer(AnObject.class, new CustomDeserializer2());
om.registerModule(module);
AnObject ob = om.readValue(json, AnObject.class);
System.out.println(ob.getValue());
System.out.println(ob.getObject().getValue1());
System.out.println(ob.getObject().getValue2());
反序列化器:
public class CustomDeserializer2 extends StdDeserializer<AnObject>
private static final long serialVersionUID = -3483096770025118080L;
public CustomDeserializer2()
this(null);
public CustomDeserializer2(Class<?> vc)
super(vc);
@Override
public AnObject deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
JsonNode interNode = jp.getCodec().readTree(jp);
AnObject ob = new AnObject();
if (interNode.get("a") != null)
ob.setValue(interNode.get("a").toString());
SomeObject obj = new SomeObject();
if (interNode.get("b") != null)
obj.setValue1(interNode.get("b").toString());
if (interNode.get("c") != null)
obj.setValue2(interNode.get("c").toString());
ob.setObject(obj);
return ob;
Model:注意A字段上的@JsonProperty
public class AnObject
@JsonProperty("a")
private String value;
private SomeObject object;
public String getValue()
return value;
public void setValue(String value)
this.value = value;
public SomeObject getObject()
return object;
public void setObject(SomeObject arg)
object = arg;
public class SomeObject
private String value1;
private String value2;
public String getValue1()
return value1;
public void setValue1(String value1)
this.value1 = value1;
public String getValue2()
return value2;
public void setValue2(String value2)
this.value2 = value2;
再见
【讨论】:
【参考方案2】:使用JsonUnwrapped
注解:
@JsonUnwrapped
private final SomeObject someObject;
它将所有SomeObject
的字段解包到父级中,在序列化时导致以下结果:
"a":"foo","b":"bar","c":"baz"
【讨论】:
我认为它只适用于序列化,我想做反序列化......但我会试一试 它也适用于反序列化。如果您无法正常工作,我可以给您一个工作示例 Effectivelyit 工作,即使文档只提到序列化。谢谢! 欢迎来到古怪的杰克逊文档世界:)【参考方案3】:使用 ObjectMapper 可以将 JSON 字符串转换为 Object。 在你的 AnObject 类中使用 JsonUnwrapped 覆盖 someObject 字段。
@JsonUnwrapped
private SomeObject someObject;
然后读取 JSON 字符串并将其转换为 AnObject。
ObjectMapper mapper = new ObjectMapper();
try
AnObject anObject1 = mapper.readValue(jsonString, AnObject.class);
catch (IOException e)
e.printStackTrace();
【讨论】:
以上是关于Jackson:映射嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章
Spring MVC 接收的 JSON 嵌套对象的 Spring Boot JACKSON 配置
如何使用 Jackson 将 JSON 键值数组动态映射到子对象?
JAVA:如何将 JSON 键值对映射到不同的变量 Jackson