好吧,当你没有太多时间的时候,评价最高的答案是一个相当快的答案,而且基本上还不错,但问题是:没有适当的关注点分离
您正在编写业务逻辑的同一位置修改序列化 JSON。您应该在 aTypeAdapter
或 a中进行所有序列化JsonSerializer
。
我们如何保持适当的关注点分离?
答案包含一些额外的复杂性,但架构需要它。我们开始吧(取自我的另一个答案):
首先,我们将为该类型使用自定义序列化程序。其次,我们必须在基类和包装子类中创建一个复制构造函数,如下所示:
注意:自定义序列化器可能看起来有点矫枉过正,但相信我,从长远来看,它会为可维护性带来回报。
.
// Lets say the base class is named Cat
public class Cat {
public String name;
public Cat(String name) {
super();
this.name = name;
}
// COPY CONSTRUCTOR
public Cat(Cat cat) {
this.name = cat.name;
}
@Override
public String sound() {
return name + " : \"meaow\"";
};
}
// The wrapper subclass for serialization
public class CatWrapper extends Cat{
public CatWrapper(String name) {
super(name);
}
public CatWrapper(Cat cat) {
super(cat);
}
}
以及类型的序列化程序Cat
:
public class CatSerializer implements JsonSerializer<Cat> {
@Override
public JsonElement serialize(Cat src, Type typeOfSrc, JsonSerializationContext context) {
// Essentially the same as the type Cat
JsonElement catWrapped = context.serialize(new CatWrapper(src));
// Here, we can customize the generated JSON from the wrapper as we want.
// We can add a field, remove a field, etc.
// The main logic from the top rated answer now here instead of *spilling* around(Kindly ignore the cat having a url for the sake of example)
return catWrapped.getAsJsonObject().addProperty("url_to_user", url);
}
}
那么,为什么要使用复制构造函数?
好吧,一旦定义了复制构造函数,无论基类发生多少变化,您的包装器都将继续扮演相同的角色。其次,如果我们不定义复制构造函数而只是将基类子类化,那么我们将不得不根据扩展类来“讨论”,即CatWrapper
. 您的组件很有可能是根据基类而不是包装器类型来讨论的。