Java – add an object using a custom typeadapter, jsonwriter in gson
Gson is a great library - it works well Sometimes I have custom requirements. I can make and register typeadapters and typeadaptorfactories, which are also very good
However, what puzzles me is how to delegate back to JSON serialization. I need this collection most of the time, but to be clear - assuming I have a pair of classes, gson will obviously enjoy serialization, but for some reason I need my own custom serializer Well, if I'm right
public class Pair { public final Object First; public final Object Second; public Pair( Object first,Object second) {this.first = first; this.second = second}; }
If I wrote a type adapter for this – you would want the write function to look like:
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(); }
So you can see this problem - I don't know the types of the first and second, or how they are serialized I can use gson Tojson serializes the first and second - but if we add them as a string to the author, they will be escaped There is a gson The tojson function needs a value and an author - but it also needs a typetoken - I don't I get the impression that I want to get from another type of adapter - but when I have only one object list... Where can I get it? I just get the object of the adapter?
I'm a little confused? Of course, is this the most common use case? Most custom serializers will be a strange list of T or T or T trees. You really don't know what in the list, except that it inherits from t... So you need to be able to delegate serialization in some way?
Anyway – I would really appreciate it if someone could tell me how to write the above features!
Solution
In this case, the jsonserializer is better used than the typeadapter because the serializer can access its serialization context:
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; } }
The above example code shows how to delegate the serialization of the target object back to the editor group Its main advantage (besides avoiding complex workarounds), you can still take advantage of other types of adapters and custom serializers that may have been registered in the main context Note that the serializer and adapter are registered using exactly the same code:
// 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();
If you find that you need to use an adapter, you can serialize your pair attribute using the embedded gson agent. The disadvantage is that you cannot access the custom registration on the parent gson agent:
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(); } }