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 {
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 {}
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>() {});
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 results
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.