【问题标题】:Jackson : map nested objectJackson:映射嵌套对象
【发布时间】: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。

标签: java jackson2


【解决方案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();
    }
    

    【讨论】:

      猜你喜欢
      • 2020-09-27
      • 2013-08-01
      • 1970-01-01
      • 2017-07-20
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多