在我的JSON中,我有一个包含以下内容的元素:
{
...
"locations": [
[
{
"location_type": "permanent",
"position": "at",
"accuracy": "exact"
},
"and",
{
"location_type": "permanent",
"position": "in",
"accuracy": "exact"
}
],
"or",
{
"location_type": "temporary",
"position": "at",
"accuracy": "exact"
}
],
...
}
如图所示,locations
的元素可以是:
我得到"无法从START_ARRAY令牌"中反序列化com.example.processor.transformation.json.Location
的实例。
如何使用Jackson将其用于数据结构?
到目前为止我尝试了什么:
Location(String logicalOperator)
构造函数有助于查找平面列表。 (我基本上将运算符转换为特殊值Location
。)Location(List<Location> subLocations)
或Location(Location[] subLocations)
构造函数对此案例没有帮助。注意:我无法控制JSON格式,所以我无法以更加杰克逊友好的方式对其进行编码。
答案 0 :(得分:1)
您需要自定义反序列化器。你不能只是添加一个构造函数。
这是一个包含类Foo
的自包含示例,可以由其自己的属性"foo" : "someString"
或某个逻辑运算符"and"
或"or"
表示等等作为String
字面值,旨在表示Foo
属性为{1}}属性的foo
实例。
这可能或可能不完全适合您的情况,但您可以调整。
换句话说:
{"foo": "a"}
- &gt; new Foo("a")
"or"
- &gt; new Foo("or")
示例强>
// given...
@JsonDeserialize(using=MyDeserializer.class)
class Foo {
String foo;
public void setFoo(String s) {
foo = s;
}
public String getFoo() {
return foo;
}
public Foo(String s) {
setFoo(s);
}
}
//和自定义反序列化器......
class MyDeserializer extends JsonDeserializer<Foo> {
@Override
public Foo deserialize(JsonParser jp, DeserializationContext ct)
throws IOException, JsonProcessingException {
ObjectCodec oc = jp.getCodec();
JsonNode node = oc.readTree(jp);
// this JSON object has a "foo" property, de-serialize
// injecting its value in Foo's constructor
if (node.has("foo")) {
return new Foo(node.get("foo").asText());
}
// other case, assuming literal (e.g. "and", "or", etc.)
// inject actual node as String value into Foo's constructor
else {
return new Foo(node.asText());
}
}
}
// here's a quick example
String json = "[{\"foo\": \"a\"}, \"or\", {\"foo\": \"b\"}]";
ObjectMapper om = new ObjectMapper();
List<Foo> list = om.readValue(json, new TypeReference<List<Foo>>(){});
list.forEach(f -> System.out.println(f.foo));
<强>输出强>
a
or
b
为清晰起见,注意
这代表了一个非常简单的例子。
在您的情况下,您可能希望将Location
POJO与LogicalOperator
POJO(或类似的东西)混合的多态集合,共享一个公共标记接口。
然后,您可以根据JSON节点是否具有内容(即位置)或JSON节点 其内容(例如逻辑运算符)来决定要反序列化的对象。