我有一个json字符串,我应该反序列化到下面的类
class Data <T> {
int found;
Class<T> hits
}
我该怎么做? 这是通常的做法
mapper.readValue(jsonString, Data.class);
但是我怎么提到T代表什么呢?
我有一个json字符串,我应该反序列化到下面的类
class Data <T> {
int found;
Class<T> hits
}
我该怎么做? 这是通常的做法
mapper.readValue(jsonString, Data.class);
但是我怎么提到T代表什么呢?
当前回答
你可以把它包装在另一个类中,这个类知道你的泛型类型的类型。
Eg,
class Wrapper {
private Data<Something> data;
}
mapper.readValue(jsonString, Wrapper.class);
这里Something是一个具体的类型。每个具体化类型都需要一个包装器。否则Jackson就不知道该创建什么对象。
其他回答
你要做的第一件事是序列化,然后你可以反序列化。 所以当你序列化时,你应该使用@JsonTypeInfo让jackson把类信息写进你的json数据。你可以这样做: 类数据<T> { int发现; @JsonTypeInfo(使用= JsonTypeInfo.Id.CLASS,包含= JsonTypeInfo.As。财产,财产= " @class”) 类< T > } 然后当你反序列化时,你会发现jackson已经将你的数据反序列化为一个类,你的变量在运行时实际上是命中的。
你可以把它包装在另一个类中,这个类知道你的泛型类型的类型。
Eg,
class Wrapper {
private Data<Something> data;
}
mapper.readValue(jsonString, Wrapper.class);
这里Something是一个具体的类型。每个具体化类型都需要一个包装器。否则Jackson就不知道该创建什么对象。
需要反序列化的JSON字符串必须包含关于参数T的类型信息。 您必须在每个可以作为参数T传递给类Data的类上添加Jackson注释,以便Jackson可以从JSON字符串中读取/写入关于参数类型T的类型信息。
让我们假设T可以是任何扩展抽象类Result的类。
class Data <T extends Result> {
int found;
Class<T> hits
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
@JsonSubTypes.Type(value = ImageResult.class, name = "ImageResult"),
@JsonSubTypes.Type(value = NewsResult.class, name = "NewsResult")})
public abstract class Result {
}
public class ImageResult extends Result {
}
public class NewsResult extends Result {
}
一旦可以作为参数T传递的每个类(或它们的公共超类型)都被注释了,Jackson将在JSON中包含关于参数T的信息。这样的JSON可以在编译时不知道参数T的情况下进行反序列化。 Jackson文档链接讨论了多态反序列化,但对于这个问题也很有用。
如果你正在使用scala,并且在编译时知道泛型类型,但不想在所有api层中手动传递TypeReference,你可以使用以下代码(使用jackson 2.9.5):
def read[T](entityStream: InputStream)(implicit typeTag: WeakTypeTag[T]): T = {
//nathang: all of this *crazy* scala reflection allows us to handle List[Seq[Map[Int,Value]]]] without passing
// new TypeReference[List[Seq[Map[Int,Value]]]]](){} to the function
def recursiveFindGenericClasses(t: Type): JavaType = {
val current = typeTag.mirror.runtimeClass(t)
if (t.typeArgs.isEmpty) {
val noSubtypes = Seq.empty[Class[_]]
factory.constructParametricType(current, noSubtypes:_*)
}
else {
val genericSubtypes: Seq[JavaType] = t.typeArgs.map(recursiveFindGenericClasses)
factory.constructParametricType(current, genericSubtypes:_*)
}
}
val javaType = recursiveFindGenericClasses(typeTag.tpe)
json.readValue[T](entityStream, javaType)
}
可以这样使用:
read[List[Map[Int, SomethingToSerialize]]](inputStream)
对于类Data<>
ObjectMapper mapper = new ObjectMapper();
JavaType type = mapper.getTypeFactory().constructParametrizedType(Data.class, Data.class, Parameter.class);
Data<Parameter> dataParam = mapper.readValue(jsonString,type)