gson是一个伟大的图书馆 – 它运作良好.有时候我有自定义的要求,可以制作和注册TypeAdapters和TypeAdaptorFactories,而且也很好.
然而,令我困惑的是如何委托回json序列化大部分时间我需要这个集合,但是要说明一点 – 假设我有一个对类,gson将显然序列化愉快,但由于某种原因我需要我自己的自定义序列化程序.好吧,如果我的对
public class Pair { public final Object First; public final Object Second; public Pair( Object first,Object second) {this.first = first; this.second = second}; }
如果我为此写了一个类型适配器 – 你会希望写入函数看起来像:
public void write( JsonWriter out,Pair pair ) { out.beginObject(); out.name( "first"); out.value( pair.first ); // can't do this out.name( "second"); out.value( pair.second); // or this out.endObject(); }
所以你可以看到这个问题 – 我不知道第一个和第二个的类型,也不知道它们是如何序列化的.我可以使用gson.toJson序列化第一个和第二个 – 但是如果我们将它们作为一个字符串添加到作者,他们将被转义.有一个gson.tojson函数需要一个值和一个作者 – 但它也需要一个typetoken – 我没有.我得到的印象是我想要从另一个类型的适配器 – 但是当我只有一个对象列表…我在哪里可以得到?我只是得到适配器的对象?
我有点困惑?当然这是最常见的用例吗?大多数自定义序列化程序将是一个T或T或T的树的奇怪列表,你真的不知道列表中的什么,除了它继承自T …所以你需要能够委托以某种方式序列化?
无论如何 – 如果有人可以告诉我如何写上述功能,我真的很感激!
解决方法
在这种情况下,更好地使用
JsonSerializer
而不是
TypeAdapter
,因为序列化程序可以访问其序列化上下文:
public class PairSerializer implements JsonSerializer<Pair> { public PairSerializer() { super(); } @Override public JsonElement serialize(final Pair value,final Type type,final JsonSerializationContext context) { final JsonObject jsonObj = new JsonObject(); jsonObj.add("first",context.serialize(value.getFirst())); jsonObj.add("second",context.serialize(value.getSecond())); return jsonObj; } }
上面的示例代码说明了如何将目标对象的序列化委托回主编组.它的主要优点(除了避免复杂的变通方法),您仍然可以利用可能已经在主要上下文中注册的其他类型的适配器和自定义序列化程序.请注意,序列化器和适配器的注册使用完全相同的代码:
// With adapter final Gson gson = new GsonBuilder().registerTypeAdapter(Pair.class,new PairAdapter()).create(); // With serializer final Gson gson = new GsonBuilder().registerTypeAdapter(Pair.class,new PairSerializer()).create();
如果您发现需要使用适配器,那么您可以使用嵌入式Gson代理序列化您的Pair属性,其缺点是您无法访问在父Gson代理上进行的自定义注册:
public class PairAdaptor extends TypeAdapter<Pair> { final Gson embedded = new Gson(); public PairAdaptor() { super(); } @Override public void write(final JsonWriter out,final Pair value) throws IOException { out.beginObject(); out.name("first"); embedded.toJson(embedded.toJsonTree(value.getFirst()),out); out.name("second"); embedded.toJson(embedded.toJsonTree(value.getSecond()),out); out.endObject(); } @Override public Pair read(JsonReader in) throws IOException { throw new UnsupportedOperationException(); } }