我想使用Gson为解析JSON创建一个解析器。
第一个IParser.java
public interface IParser<T> {
public T parse(String json);
}
第二个Parser.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
public class Parser<T> implements IParser<T> {
@Override
public T parse(String json) {
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.enableComplexMapKeySerialization().create();
MyJson<T> jsonParsed = gson.fromJson(json, new TypeToken<MyJson<T>>() {
}.getType());
System.out.println(jsonParsed.toString());
return null;
}
}
第三个MyJson.java
public class MyJson<T> {
private int status;
private T data;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
User.java
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private long usrId;
private String usrNm;
private String usrPwd;
private String usrEml;
public User() {
}
public long getUsrId() {
return usrId;
}
public void setUsrId(long usrId) {
this.usrId = usrId;
}
public String getUsrNm() {
return usrNm;
}
public void setUsrNm(String usrNm) {
this.usrNm = usrNm;
}
public String getUsrPwd() {
return usrPwd;
}
public void setUsrPwd(String usrPwd) {
this.usrPwd = usrPwd;
}
public String getUsrEml() {
return usrEml;
}
public void setUsrEml(String usrEml) {
this.usrEml = usrEml;
}
@Override
public String toString() {
return "User [usrId=" + usrId + ", usrNm=" + usrNm + ", usrPwd="
+ usrPwd + ", usrEml=" + usrEml + "]";
}
}
我的JSON字符串:
{
status: 200,
data: {
usrId: 2,
usrNm: "John",
usrPwd: "123",
usrEml: "john@test.com"
}
}
我想在jsonString上解析为MyJson<T>
对象。
我做:
MyJson<T> jsonParsed = gson.fromJson(json, new TypeToken<MyJson<T>>() {
}.getType());
=&GT; Gson
将User
中的MyJson
解析为LinkedTreeMap
意思是:Object data = jsonParsed.getData();
=&gt; LinkedTreeMap
我想要的是:User
但是,当我尝试:
MyJson<User> jsonParsed = gson.fromJson(json, new TypeToken<MyJson<User>>() {
}.getType());
gson工作正常。
所以我想知道我怎么能用第一种方式使gson正常工作(使用T而不是User),因为我想用 Parser
来解析其他对象感谢您的帮助。
答案 0 :(得分:3)
@Override
public T parse(String json, Type type) {
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.enableComplexMapKeySerialization().create();
MyJson<T> jsonParsed = gson.fromJson(json, type);
System.out.println(jsonParsed.toString());
return null;
}
使用:
User user = myJson.parse(jsonString, new TypeToken<User>() {
}.getType());
答案 1 :(得分:2)
正如其他人所指出的那样,问题是TypeToken
必须用所有具体类型进行实例化(即不用任何T
参数化)。所以你需要调用者为你实例化TypeToken
(&#34;你&#34;这里是Parser
类。)
John接受的答案是有效的(如果你忽略它返回null
并打印结果的事实),但我认为强制执行Type
参数更好与返回类型的兼容性,如下所示:
public T parse(String json, TypeToken<MyJson<T>> typeToken) {
MyJson<T> deserializedMyJson = gson.fromJson(json, typeToken.getType());
return deserializedMyJson.getData();
}
它会在编译时强制执行对parse()
的任何调用都传递正确的TypeToken
,以便类似
A a = parser.parse(jsonString, new TypeToken<MyJson<B>>(){}); // incorrect
将在编译时失败,而类似这样的事情(假设parse()
方法将Type
作为参数):
A a = parser.parse(jsonString, new TypeToken<MyJson<B>>(){}.getType()); // incorrect too, but will compile
只会在运行时失败(尝试将B
执行的parse()
结果转换为a
类型的A
变量时。