I'm using Gson in a slightly "different" way and I'm wondering if the following is possible...
I'd like to change the default serialization/deserialization format for enums so that it uses fully-qualified class names, but maintain support for the @SerializedName annotation on said enums. Basically, given the following enum...
package com.example;
public class MyClass {
public enum MyEnum {
OPTION_ONE,
OPTION_TWO,
@SerializedName("someSpecialName")
OPTION_THREE
}
}
I'd like the following to be true...
gson.toJson(MyEnum.OPTION_ONE) == "com.example.MyClass.MyEnum.OPTION_ONE"
&&
gson.toJson(MyEnum.OPTION_TWO) == "com.example.MyClass.MyEnum.OPTION_TWO"
&&
gson.toJson(MyEnum.OPTION_THREE) == "someSpecialName"
and vice-versa.
(for those curious, I'm trying to build a small lib that allows me to treat android's intent's actions as enums, so that I can write switch statements instead of a bunch of ugly if-elses + string compares, and I want to support the annotation so that I can also include custom pre-existing action strings like Intent.ACTION_VIEW, etc in the same enum).
So would anyone know if it's possible to register a type adapter that can fall back if the @SerializedName field is present? Would I just have to check for that annotation myself in my own TypeAdapter?
Thanks in advance.
Because enums are automatically Serializable (see Javadoc API documentation for Enum), there is no need to explicitly add the "implements Serializable" clause following the enum declaration.
In order to serialize Enum, we take the help of ObjectMapper class. We use the writeValueAsString() method of ObjectMapper class for serializing Enum. If we serialize Enum by using the writeValueAsString() method, it will represent Java Enums as a simple string.
In C#, enums are backed by an integer. Most tools will serialize or save your enums using that integer value.
I created pretty nice solution for this issue :
package your.package.name
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Field;
public class EnumAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
Class<? super T> rawType = type.getRawType();
if (rawType.isEnum()) {
return new EnumTypeAdapter<T>();
}
return null;
}
public class EnumTypeAdapter<T> extends TypeAdapter<T> {
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
Enum<?> realEnums = Enum.valueOf(value.getClass().asSubclass(Enum.class), value.toString());
Field[] enumFields = realEnums.getClass().getDeclaredFields();
out.beginObject();
out.name("name");
out.value(realEnums.name());
for (Field enumField : enumFields) {
if (enumField.isEnumConstant() || enumField.getName().equals("$VALUES")) {
continue;
}
enumField.setAccessible(true);
try {
out.name(enumField.getName());
out.value(enumField.get(realEnums).toString());
} catch (Throwable th) {
out.value("");
}
}
out.endObject();
}
public T read(JsonReader in) throws IOException {
return null;
}
}
}
and of course :
new GsonBuilder().registerTypeAdapterFactory(new EnumAdapterFactory()).create();
Hope this helps !
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With