gpt4 book ai didi

json - 使用 Jackson 映射可以具有不同类型的 JSON 字段?

转载 作者:行者123 更新时间:2023-12-04 11:59:10 26 4
gpt4 key购买 nike

我从 Web 服务获取 JSON 并且无法影响 JSON 格式。下面的 JSON 代码只是说明问题的一个例子。领域cars可以是包含 Car 的对象对象或者它可以是一个空字符串。如果我可以更改 Web 服务,我会将空字符串更改为空对象,例如 "cars" : {}而不是 "cars" : "" .

尝试将 JSON 映射到此 Java 对象时:

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

这有效:
{
"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"
}
}
}

这失败了:
{
"id" : "1",
"name" : "The Dude",
"cars" : ""
}

在 jackson 处理此案的最佳方法是什么?如果有空字符串,我想得到 null领域 cars .我尝试使用 ACCEPT_EMPTY_STRING_AS_NULL_OBJECT ,但这没有帮助。

最佳答案

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”元素值不是列表(又名数组)。它是一个 JSON 对象,也可以认为是一个 map 类型的集合,但它不是一个列表。

因此,重新表述这个问题,目标是将有时是对象、有时是空字符串的 JSON 反序列化为 Java Map .

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

您可以实现 custom deserialization .以下是一个示例解决方案。如果目标数据结构有其他 Map引用,那么这个解决方案需要相应地改变。
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
}
}

关于json - 使用 Jackson 映射可以具有不同类型的 JSON 字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6684358/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com