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 键值数组动态映射到子对象?

jackson中objectMapper的使用

JAVA:如何将 JSON 键值对映射到不同的变量 Jackson

如何在JAVA中用JACKSON映射一个JSON中的数组,这个数组可以包含不同类型的对象作为项目?

如何在JAVA中用JACKSON映射一个JSON中的数组,这个数组可以包含不同类型的对象作为项目?