user905686 user905686 - 1 month ago 7
Java Question

Why does GSON produce different JSON for enum at custom TypeAdapter?

I wrote a

TypeAdapter
for a class that contains an enum attribute. This is the
write
method, which uses standard GSON serialization for the enum value:

@Override
public void write(JsonWriter writer, MyClass object) throws IOException {
if (object == null) {
writer.nullValue();
return;
}
writer.beginObject();
writer.name("type").value(gson.toJson(object.getType())); //this is the enum
writer.endObject();
}


When using this
TypeAdapter
, the produced JSON contains this part for the enum:

"type":"\"ENUM_VALUE\""


But when I use
gson.toJson(object)
on a class which contains this enum without a TypeAdapter, it produces:

"type":"ENUM_VALUE"


All
Gson
objects use the standard configuration. It produces the same result in the first version, whether I test the
TypeAdapter
directly or use a
Gson
and registering it.

Why is there a difference? I guess escaping is not needed here, so I’d like to avoid it.
Interestingly, deserialization works for both serialized versions with the
TypeAdapter
(with
gson.fromJson(reader.nextString())
).

I guess that the problem might occure because
gson.toJson(object.getType())
already produces quotes:
"ENUM_VALUE"
and when adding them to the
JsonWriter
with
writer.value(gson.toJson(object.getType())
it gets escaped. But how to handle this correctly, like GSON does it?

Answer

Simply your TypeAdapter is wrong. Replace it with:

public void write(JsonWriter writer, MyClass object) throws IOException {
    if (object == null) {
        writer.nullValue();
        return;
    }
    writer.beginObject();
    writer.name("type").value(object.getType().toString()); //this is the enum
    writer.endObject();
}

In your code, you create a string from the enum doing a JSON serialization. This produces "ENUM_VALUE" (gson.toJson(object.getType())), and then it is serialized again into a string so the result is \"ENUM_VALUE\".

In my code, I get the string representation of the enum using the toString() method so no additional quotes are created.