且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

映射与Jackson有不同类型的JSON字段?

更新时间:2022-12-28 23:36:33


现场汽车可以包含汽车对象列表
...
这样可行:

The field cars can either contain a list of Car objects ... This works:



{
    "id" : "1234",
    "name" : "John Doe",
    "cars" : {
        "Tesla Model S" : {
            "color" : "silver",
            "buying_date" : "2012-06-01"
        },
        "Toyota Yaris" : {
            "color" : "blue",
            "buying_date" : "2005-01-01"
        }
    }
}

cars元素值不是列表(aka数组)。它是一个JSON对象,也可以被认为是一个map类型的集合,但它不是一个列表。

The "cars" element value is not a list (aka array). It's a JSON object, which can also be considered a map-type collection, but it is not a list.

因此,为了重新解释这个问题,目标是反序列化JSON有时是一个对象,有时候是一个空字符串到Java Map

So, to rephrase the issue, the goal is to deserialize JSON that is sometimes an object and sometimes an empty string into a Java Map.

为了解决这个问题,我'我很惊讶 ACCEPT_EMPTY_STRING_AS_NULL_OBJECT 无效。我建议在 http://jira.codehaus.org/browse/JACKSON 上记录问题。

To solve this, I'm surprised ACCEPT_EMPTY_STRING_AS_NULL_OBJECT didn't work. I recommend logging an issue at http://jira.codehaus.org/browse/JACKSON.

您可以实施自定义反序列化。以下是一个示例解决方案。如果目标数据结构具有其他 Map 引用,则需要相应地更改此解决方案。

You could implement custom deserialization. Following is an example solution. If the target data structure has other Map references, then this solution would need to be accordingly changed.

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.ObjectCodec;
import org.codehaus.jackson.Version;
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;
import org.codehaus.jackson.type.TypeReference;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    SimpleModule module = new SimpleModule("CarsDeserializer", Version.unknownVersion());
    module.addDeserializer(Map.class, new CarsDeserializer());

    ObjectMapper mapper = new ObjectMapper().withModule(module);

    Person person1 = mapper.readValue(new File("input1.json"), Person.class);
    System.out.println(mapper.writeValueAsString(person1));
    // {"id":1234,"name":"John Doe","cars":{"Tesla Model S":{"color":"silver","buying_date":"2012-06-01"},"Toyota Yaris":{"color":"blue","buying_date":"2005-01-01"}}}

    Person person2 = mapper.readValue(new File("input2.json"), Person.class);
    System.out.println(mapper.writeValueAsString(person2));
    // {"id":1,"name":"The Dude","cars":{}}
  }
}

class Person
{
  public int id;
  public String name;
  public Map<String, Car> cars;
}

class Car
{
  public String color;
  public String buying_date;
}

class CarsDeserializer extends JsonDeserializer<Map<String, Car>>
{
  @Override
  public Map<String, Car> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
      JsonProcessingException
  {
    ObjectCodec codec = jp.getCodec();
    JsonNode node = codec.readTree(jp);
    if (!"".equals(node.getTextValue()))
    {
      ObjectMapper mapper = new ObjectMapper();
      return mapper.readValue(node, new TypeReference<Map<String, Car>>() {});
    }
    return new HashMap<String, Car>(); // or return null, if preferred
  }
}