当前位置: 首页 > 知识库问答 >
问题:

Jackson:如何使用速记属性值反序列化json

法镜
2023-03-14

我正在努力找出如何使用杰克逊将具有速记约定的 JSON 反序列化为 Java POJO。

[
  { 
    "id":1,
    "type": "simple"
  },
  { 
    "id":2,
    "type": { "kind": "simple" }
  },
  { 
    "id":3,
    "type": {
      "kind": "complex",
      "someOtherThing": "value"
    }
  }
]

这里的“类型”属性可以是字符串或对象。如果它是一个字符串,那么它被认为是具有默认属性的同一对象的简单简写形式。一、 上例中的1和2是等效的。

据我所知,可以为整个“类型”对象编写自定义反序列化器。据我所知,在这种情况下,我必须手动反序列化整个“类型”对象。但是我真的想只手动处理速记形式,并将正常处理委托给基于注释的映射器。这可能吗?

共有2个答案

狄宗清
2023-03-14

您可能需要为< code>type编写一个自定义的< code>BeanDeserializer子类。然而,您可以利用Jackson的其余部分来处理类型对象。

最好的选择是<code>@JsonIgnore</code>对象中的类型属性。然后,在自定义反序列化程序中,重写handleIgnoredProperty()。在此方法中,请执行以下操作:

protected void handleIgnoredProperty(JsonParser jp, DeserializationContext ctxt, Object beanOrClass, String propName)
        throws IOException, JsonProcessingException {
  if ("type".equals(propName)) {
     if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
       MyObjectDeserializer myObjectDeserializer = (MyObjectDeserializer) ctxt.findRootValueDeserializer(ctxt                   .getTypeFactory().constructType(MyObject.class));
       MyObject myObject = (MyObject) myObjectDeserializer.deserialize(jp, ctxt);
       // cast beanOrClass to your object and call object.setType(myObject)
     }
     else {
        // get a StringDeserializer and call object.setType(string)
     }
  }
  else {
    super.handleIgnoredProperty(jp, ctxt, beanOrClass, propName);
  }
}

您可能需要做一些更多的处理来手动读取jp.nextToken()的种类值,以获得某个其他东西,但我希望这足以让您开始。

连德义
2023-03-14

您可以简单地使用参数定义构造函数,该参数将创建具有简单类型的对象。在您的情况下,您的Type类将具有String构造函数。不要忘记也包含noargs构造函数。

public static void main(String [] args) throws JsonParseException, JsonMappingException, IOException {
    String str = "[ {\"id\":1,\"type\":\"simple\" }, {\"id\":2,\"type\": {\"kind\":\"simple\" } }, {\"id\":3,\"type\": {\"kind\":\"complex\",\"someOtherThing\":\"value\" } }]";
    ObjectMapper mapper = new ObjectMapper();
    MyObject[] objs = mapper.readValue(str.getBytes(), MyObject[].class);
    for(MyObject obj : objs) {
        System.out.println(obj.id + " " + obj.type.kind + " " + obj.type.someOtherThing);
    }
}

public static class MyObject {
    public String id;
    public Type type;
}

public static class Type {
    public String kind;
    public String someOtherThing;

    public Type() {
    }

    public Type(String kind) {
        this.kind = kind;
    }
}

打印出来

1 simple null
2 simple null
3 complex value
 类似资料:
  • 问题内容: 使用Jackson 2,我正在寻找一种 通用的 方式将对象序列化为单个值(然后序列化它们,然后再填充该单个字段),而不必重复创建JsonSerializer / JsonDeserializer来处理每种情况。@JsonIdentityInfo批注非常接近,但由于我知道,它将始终对完整的子对象进行序列化,因此略微遗漏了该标记。 这是我想做的一个例子。给定的类: 我希望Order可以序列

  • 我想用Jackson 2.13.1反序列化一个枚举。 我找到了以下解决方案。 仍将收到以下错误:

  • 来自REST服务的json对象 使用JacksonInFiveMinutes中的代码 ObjectMapper mapper=new ObjectMapper(); Map userData=mapper.read值(webResource.queryParams(queryParams). get(String.class);, Map.class); 在哪里: 从REST服务返回json 从J

  • 我正在寻找一种解决方案,使用Jackson基于同一POJO中的其他属性值序列化POJO对象属性 如果某个属性值符合某些条件,则应根据要求更改其他属性值 例如,下面是我的JSON对象: 在上述情况下,如果的值符合某些条件,那么我应该能够更改的值 为什么需要这样做: 是一个配置对象 和-是配置设置 在上面的例子中,中有一个是,我需要屏蔽/更改相应的 还要补充一点,在这个例子中,属性是和,但是如果我们找