下面的示例显示了一个类(Club),其中包含抽象类(成员)的集合。我对于是否需要TypeAdapter或JsonDeserializer才能使反序列化正常工作感到困惑。序列化在没有任何帮助的情况下就可以正常工作,但是反序列化会引发异常。为了说明这一点,我构建了以下“克隆”测试。如果有人能展示一个有效的例子,我将不胜感激。
头等舱
package gson.test;
import java.util.ArrayList;
import com.google.gson.Gson;
public class Club {
public static void main(String[] args) {
// Setup a Club with 2 members
Club myClub = new Club();
myClub.addMember(new Silver());
myClub.addMember(new Gold());
// Serialize to JSON
Gson gson = new Gson();
String myJsonClub = gson.toJson(myClub);
System.out.println(myJsonClub);
// De-Serialize to Club
Club myNewClub = gson.fromJson(myJsonClub, Club.class);
System.out.println(myClub.equals(myNewClub) ? "Cloned!" : "Failed");
}
private String title = "MyClub";
private ArrayList<Member> members = new ArrayList<Member>();
public boolean equals(Club that) {
if (!this.title.equals(that.title)) return false;
for (int i=0; i<this.members.size(); i++) {
if (! this.getMember(i).equals(that.getMember(i))) return false;
}
return true;
}
public void addMember(Member newMember) { members.add(newMember); }
public Member getMember(int i) { return members.get(i); }
}
现在是抽象基类成员
package gson.test;
public abstract class Member {
private int type;
private String name = "";
public int getType() { return type; }
public void setType(int type) { this.type = type; }
public boolean equals(Member that) {return this.name.equals(that.name);}
}
以及成员的两个具体子类(金和银)
package gson.test;
public class Gold extends Member {
private String goldData = "SomeGoldData";
public Gold() {
super();
this.setType(2);
}
public boolean equals(Gold that) {
return (super.equals(that) && this.goldData.equals(that.goldData));
}
}
package gson.test;
public class Silver extends Member {
private String silverData = "SomeSilverData";
public Silver() {
super();
this.setType(1);
}
public boolean equals(Silver that) {
return (super.equals(that) && this.silverData.equals(that.silverData));
}
}
最后是输出
{"title":"MyClub","members":[{"silverData":"SomeSilverData","type":1,"name":""},{"goldData":"SomeGoldData","type":2,"name":""}]}
Exception in thread "main" java.lang.RuntimeException: Failed to invoke public gson.test.Member() with no args
at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:107)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:186)
...
你们两个都可以。您选择哪一个真正取决于对性能的潜在影响,以及愿意编写多少代码。
解串器更昂贵。这是因为反序列化器的输入是一棵json树,GSon必须先创建一个与您的类匹配的属性的完整JsonElement子树,然后才能将其传递给反序列化器。如果您的课程有很多嵌套,那么成本会增加。对于普通物体,它可以忽略不计。
似乎您将基于type
将包含在目标对象中的属性的值来知道要创建哪个类。您的解串器将需要
JsonElement
对象,读取type
属性,确定类型context.deserialize()
用类和传递给您的相同元素进行调用您的类型适配器必须更复杂。类型适配器的输入是流,而不是元素/子树。您可以完全从流中加载下一个值,对其进行解析,然后完全执行解串器的操作,这没有任何意义,您可以使用解串器接口。另外,您可以读取流,查看有哪些属性,将它们保存到局部变量中,直到到达type
属性(无法预测其位置),然后完成读取其余属性,并创建最终的Gold
/
Silver
基于类型的对象,并读取和保存所有属性。
主要内容:创建自定义适配器,注册自定义适配器,使用适配器Gson使用其内置适配器执行对象的序列化/反序列化。 它也支持自定义适配器。 让我们来讨论如何创建一个自定义适配器以及如何使用它。 创建自定义适配器 通过扩展类并传递目标类型的对象来创建自定义适配器。 重写读写方法分别执行自定义的反序列化和序列化。 注册自定义适配器 使用注册自定义适配器并使用创建一个Gson实例。参考以下实现代码 - 使用适配器 Gson现在将使用自定义适配器将Json文本转换为
问题内容: 我的探针示例: 我们有Apple的对象类型。苹果有一些成员变量: 种子对象如下所示。 现在,当我得到一个苹果物体时,一个苹果可能有多个种子,或者可能有一个种子,或者可能没有种子! 带有一个种子的示例JSON苹果: 带有两个种子的示例JSON苹果: 现在的问题是,第一个示例是用于种子的JSONObject,第二个示例是用于种子的JSONArray。现在,我知道它的JSON不一致,并且最简
问题内容: 我的探针示例: 我们有Apple的对象类型。苹果有一些成员变量: 种子对象如下所示。 现在,当我得到一个苹果物体时,一个苹果可能有多个种子,或者可能有一个种子,或者可能没有种子! 带有一个种子的示例JSON苹果: 带有两个种子的示例JSON苹果: 现在的问题是,第一个示例是用于种子的JSONObject,第二个示例是用于种子的JSONArray。现在,我知道它的JSON不一致,并且最简
英文原文:http://emberjs.com/guides/models/customizing-adapters/ 在Ember Data中,处理与后台数据仓库通信的逻辑是通过Adapter来完成的。Ember Data适配器内置了一些关于REST API的假定。如果后台的实现与Ember Data假定的惯例不同,那么通过扩展缺省的适配器可能很容易的实现。 有时因为一些原因需要自定义适配器,例
Gson使用其内置适配器执行对象的序列化/反序列化。 它还支持自定义适配器。 我们将讨论如何创建自定义适配器以及如何使用它。 创建自定义适配器 通过扩展TypeAdapter类并将其传递给目标对象的类型来创建自定义适配器。 重写read和write方法以分别执行自定义反序列化和序列化。 class StudentAdapter extends TypeAdapter<Student> {
改型异步请求是用两个方法onResponse()和onFailure()回调的。 我还想使用Gson转换器来转换改型响应,然后用APIPesponse包装它。 如果我用like 好像不起作用。不能将json响应数据解析到结果对象中。 有人能帮助如何让用调用enqueue吗?结果是使用Gson转换器解析json数据内容。 有人能帮我指出这个问题吗?