杰克逊反序列化对象或数组 [英] Jackson deserialize object or array

查看:129
本文介绍了杰克逊反序列化对象或数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个杰克逊问题。

有没有办法对可能有两种类型的属性进行反序列化,对于某些对象,它看起来像这样

Is there a way to deserialize a property that may have two types, for some objects it appears like this

"someObj" : { "obj1" : 5, etc....}

然后对于其他人来说它显示为空数组,即

then for others it appears as an empty array, i.e.

"someObj" : []

任何帮助表示赞赏!

谢谢!

推荐答案

杰克逊目前没有内置配置来自动处理这种特殊情况,所以自定义反序列化处理是必要的。

Jackson doesn't currently have a built-in configuration to automatically handle this particular case, so custom deserialization processing is necessary.

以下是这种自定义反序列化的示例。

Following is an example of what such custom deserialization might look like.

import java.io.IOException;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.module.SimpleModule;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    // {"property1":{"property2":42}}
    String json1 = "{\"property1\":{\"property2\":42}}";

    // {"property1":[]}
    String json2 = "{\"property1\":[]}";

    SimpleModule module = new SimpleModule("", Version.unknownVersion());
    module.addDeserializer(Thing2.class, new ArrayAsNullDeserializer());

    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY).withModule(module);

    Thing1 firstThing = mapper.readValue(json1, Thing1.class);
    System.out.println(firstThing);
    // output:
    // Thing1: property1=Thing2: property2=42

    Thing1 secondThing = mapper.readValue(json2, Thing1.class);
    System.out.println(secondThing);
    // output: 
    // Thing1: property1=null
  }
}

class Thing1
{
  Thing2 property1;

  @Override
  public String toString()
  {
    return String.format("Thing1: property1=%s", property1);
  }
}

class Thing2
{
  int property2;

  @Override
  public String toString()
  {
    return String.format("Thing2: property2=%d", property2);
  }
}

class ArrayAsNullDeserializer extends JsonDeserializer<Thing2>
{
  @Override
  public Thing2 deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException
  {
    JsonNode node = jp.readValueAsTree();
    if (node.isObject())
      return new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY).readValue(node, Thing2.class);
    return null;
  }
}

(您可以使用DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY强制输入始终绑定到集合,但这可能不是我采用的方法,因为目前如何描述问题。)

(You could make use of DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY to force the input to always bind to a collection, but that's probably not the approach I'd take given how the problem is currently described.)

这篇关于杰克逊反序列化对象或数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆