使用GSON或Jackson将JSON反序列化为具有泛型参数的类 [英] Deserializing JSON into a class with a generic argument using GSON or Jackson

查看:669
本文介绍了使用GSON或Jackson将JSON反序列化为具有泛型参数的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  {
timestamp:1,
其他一些数据:blah,
result:{
...
}
}

用于多种呼叫。我想做客户端的是:

  class ServerResponse< T> {
long timestamp;
T结果;

}

然后用GSON或Jackson将其反序列化。我一直无法这样做,感谢类型擦除。我欺骗了使用这样的子类:

  class SpecificResponse扩展了ServerRequest< SpecificType> {} 

但是这需要大量无用的类来存放。任何人都有更好的方法?

我还需要能够处理结果为数组的情况。

在这种情况下,输入删除的典型解决方案是 type token hack 利用匿名类维护超类信息用于反射。



Jackson提供了 TypeReference 类型以及 ObjectMapper#readValue 重载使用它。



在你的例子中,你可以使用

  ServerR esponse response = objectMapper.readValue(theJsonSource,new TypeReference< ServerResponse< SpecificType>>(){}); 

请注意,这不是类型安全的,因此您必须注意您要分配的类型与您在匿名类实例创建表达式中使用的泛型类型参数兼容。




至于支持JSON中的单个值和数组,您可以将字段更改为集合类型。例如,

 列表< T>结果

然后,启用 DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY


确定强制使用Java集合的非数组
(使用JSON)值是否可以接受(数组
java.util.Collection )类型。如果启用,集合反序列化器将
尝试处理非数组值,就好像它们具有隐式周围的
JSON数组一样。



I'm getting responses from my server that look like:

{
  "timestamp" : 1,
  "some other data": "blah",
  "result" : {
     ...
  }
}

for a variety of calls. What I want to do client side is:

class ServerResponse<T> {
    long timestamp;
    T result;

}

and then deserialize that with GSON or Jackson. I've been unable to do so thanks to type erasure. I've cheated that using subclasses like this:

class SpecificResponse extends ServerRequest<SpecificType> {}

but that requires a bunch of useless classes to lie around. Anyone have a better way?

I also need to be able to handle the case of result being an array.

解决方案

The typical solution to type erasure in this case is the type token hack which takes advantage of anonymous classes maintaining superclass information for use with reflection.

Jackson provides the TypeReference type as well as an ObjectMapper#readValue overload to use it.

In your example, you'd use

ServerResponse response = objectMapper.readValue(theJsonSource, new TypeReference<ServerResponse<SpecificType>>() {});

Note that this is not type-safe so you must be careful that the type you try to assign to is compatible with the generic type argument you used in the anonymous class instance creation expression.


As for supporting both single values and arrays in the JSON, you can change your field to be of some Collection type. For example,

List<T> results

Then, enable DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY.

Feature that determines whether it is acceptable to coerce non-array (in JSON) values to work with Java collection (arrays, java.util.Collection) types. If enabled, collection deserializers will try to handle non-array values as if they had "implicit" surrounding JSON array.

这篇关于使用GSON或Jackson将JSON反序列化为具有泛型参数的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆