我目前正在编写一款Android应用,它使用Google的GSON库进行JSON反序列化。我刚刚解决了这个问题(或者至少是一个非常类似的)问题,但我的源文件丢失了,因为我在设置备份过程时犯了一个错误。无论如何,我知道有一个解决方案。 ; - )
我要序列化的JSON来自以下列形式发送数据的Web服务器:
{
"version": "1.1",
"error": {
"name": "bla",
"code": 1234,
"message": "oops"
},
"result": ???
}
error
或result
始终为null
,具体取决于我的请求是否可以处理。 result
可以是boolean
到非常复杂的类。
我的Java代码结构如下所示:
public class Response<T> {
private String version;
private T result;
private Error error;
public Response() {
}
public boolean isError() {
return error != null;
}
public String getVersion() {
return version;
}
public T getResult() {
return result;
}
}
public class Error {
private String name;
private int code;
private String message;
public Error() {
}
public String getName() {
return name;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
当我尝试反序列化Response<Boolean>
甚至Response<ArrayList<String>>
时,一切正常,但我有点困惑,因为Response<String[]>
无法正常工作。即使error
字段也正确填充。无论如何,有一件事绝对无法正常工作,Response<Device>
其中Device
是一个非常简单的类,如下所示:
public class Device {
public String id;
public String name;
public String address;
public String type;
}
最后,这是我的反序列化代码:
private <T> Response<T> sendCommand(/* ... */) {
Gson gson = new Gson();
// preparing and sending request etc.
String responseJson = "..."; // response JSON is valid (already verified)
Type t = new TypeToken<Response<T>>() { }.getType();
Response<T> result = gson.fromJson(responseJson, t);
return result;
}
private void doSomething() {
Response<Device> response = sendCommand("getSomeDevice");
}
我用Google搜索过去三个小时,但我找不到任何解决方案。 (也许这是一个基本的Java问题,我通常用C#编写代码。)任何人都可以帮助我吗?
修改 的
我忘了提到当我调试代码时,似乎GSON将Device
JSON反序列化为LinkedTreeMap
类型的对象。不知道这意味着什么,但也许它可以帮助你。
答案 0 :(得分:2)
问题可能在这里:
Type t = new TypeToken<Response<T>>() { }.getType();
由于type erasure,T
将无法在运行时解析。它需要由调用者传递一个适当的可再生类型令牌:
private <T> Response<T> sendCommand(/* ... */, TypeToken<Response<T>> type) {
Gson gson = new Gson();
// preparing and sending request etc.
String responseJson = "..."; // response JSON is valid (already verified)
Response<T> result = gson.fromJson(responseJson, type.getType());
return result;
}
private void doSomething() {
TypeToken<Response<T>> type = new TypeToken<Response<Device>>() { };
Response<Device> response = sendCommand("getSomeDevice", type);
}
使用Guava的TypeToken
版本,可以进一步抽象出来:
private <T> Response<T> sendCommand(/* ... */, TypeToken<T> responseType) {
Gson gson = new Gson();
// preparing and sending request etc.
String responseJson = "..."; // response JSON is valid (already verified)
Type type = new TypeToken<Response<T>>() { }
.where(new TypeParameter<T>() { }, responseType)
.getType();
Response<T> result = gson.fromJson(responseJson, type);
return result;
}
private void doSomething() {
Response<Device> response =
sendCommand("getSomeDevice", new TypeToken<Device>() { });
}