【发布时间】:2015-04-06 12:45:03
【问题描述】:
摘要
我正在使用 JsonPath 选择 JSON 文件的一部分并将其反序列化为 POJO。这适用于字符串,但我不知道如何让杰克逊将三元素数组反序列化为我自己的类 (Vector3d) 的单个实例。 Jackson 文档中的所有示例似乎都涉及将 JSON 中的元素转换为一个 Java 对象。有什么想法吗?
文档内容
JsonPath documentation 提到了这一点
如果您将 JsonPath 配置为使用 JacksonMappingProvider,您甚至可以将 JsonPath 输出直接映射到 POJO。
Book book = JsonPath.parse(json).read("$.store.book[0]", Book.class);
但我无法让它工作。
我的尝试
我的Vector3d 类如下所示(注意@JsonCreator 构造函数):
import com.fasterxml.jackson.annotation.JsonCreator;
public final class Vector3d {
private final int x, y, z;
public Vector3d(int x, int y, int z) {
this.x = x; this.y = y; this.z = z;
}
@JsonCreator
public Vector3d(int[] values) {
this(values[0], values[1], values[2]);
}
}
对于这个例子(我使用的实际文件更复杂):
{
type: "viper",
location: [
20,
173,
153
]
}
我可以将“位置”向量作为一个三元素数组,如下所示(这段代码过于冗长,但只是为了让下一步保持小规模):
package main;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.internal.JsonReader;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
import java.util.Arrays;
public class Tester {
public static void main(String[] args) throws Exception {
Configuration configuration = Configuration.defaultConfiguration();
MappingProvider mappingProvider = new JacksonMappingProvider();
configuration.mappingProvider(mappingProvider);
JsonReader jsonReader = new JsonReader(configuration);
DocumentContext documentContext = jsonReader.parse("{\n" +
"\ttype: \"viper\",\n" +
"\tlocation: [\n" +
"\t\t20,\n" +
"\t\t173,\n" +
"\t\t153\n" +
"\t]\n" +
"}");
int[] data = documentContext.read("$.location", int[].class);
System.out.println(Arrays.toString(data));
}
}
但如果我在最后一行使用 Vector3d 而不是 int[],我会在 read() 调用期间遇到异常:
java.lang.RuntimeException: Invalid or non Implemented status createArray() in class net.minidev.json.writer.BeansMapper$Bean
at net.minidev.json.writer.JsonReaderI.createArray(JsonReaderI.java:98)
at net.minidev.json.parser.JSONParserBase.readArray(JSONParserBase.java:235)
at net.minidev.json.parser.JSONParserBase.readFirst(JSONParserBase.java:298)
at net.minidev.json.parser.JSONParserBase.parse(JSONParserBase.java:154)
at net.minidev.json.parser.JSONParserString.parse(JSONParserString.java:58)
at net.minidev.json.parser.JSONParser.parse(JSONParser.java:261)
at net.minidev.json.JSONValue.parse(JSONValue.java:206)
at com.jayway.jsonpath.spi.mapper.JsonSmartMappingProvider.map(JsonSmartMappingProvider.java:86)
at com.jayway.jsonpath.internal.JsonReader.convert(JsonReader.java:174)
at com.jayway.jsonpath.internal.JsonReader.read(JsonReader.java:140)
at main.Tester.main(Tester.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
我很困惑 Vector3d 构造不起作用,尽管反序列化为 int[] 有效,并添加了采用 int[] 的 @JsonCreator 构造函数。有任何想法吗?
【问题讨论】: