我正在通过Gson反序列化(.toJson)为Enums
国际化提供一个很好的解决方案。
现在我有了:
private static final class GenericEnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
private ResourceBundle bundle = ResourceBundle.getBundle("Messages");
private Class<T> classOfT;
public GenericEnumTypeAdapter(Class<T> classOfT) {
this.classOfT = classOfT;
}
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return Enum.valueOf(classOfT, in.nextString());
}
public void write(JsonWriter out, T value) throws IOException {
out.value(value == null ? null : bundle.getString("enum." + value.getClass().getSimpleName() + "."
+ value.name()));
}
}
此解决方案的问题是:对于每个枚举,您应该注册一个新的适配器:
gsonBuilder.registerTypeAdapter(EventSensorState.class,
new GenericEnumTypeAdapter<>(FirstEnum.class)
有人有想法做得更好吗?
答案 0 :(得分:0)
使用TypeAdapterFactory
生成所有适配器。请参阅 How do I implement TypeAdapterFactory in Gson?
要将TypeAdapter
转换为TypeAdapterFactory
,关键是正确检测课程,然后使用create
方法。警告:此解决方案将在您的系统中注册每种类型的枚举;您可能必须将其调整为仅与实现特定接口的Enum
一起使用,或者使用子类注册Enum
类等。我创建了一个EnumGenerator
类来执行大部分操作阅读转换的工作,你应该能够自己弄清楚。
public class EnumAdapterFactory implements TypeAdapterFactory {
private final ResourceBundle bundle;
private final EnumGenerator generator;
public EnumAdapterFactory(ResourceBundle bundle, EnumGenerator generator) {
this.bundle = bundle;
this.generator = generator;
}
@SuppressWarnings("unchecked")
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (!Enum.class.isAssignableFrom(type.getRawType())) return null;
return (TypeAdapter<T>) new GenericEnumTypeAdapter();
}
private final class GenericEnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return generator.create(in.nextString());
}
public void write(JsonWriter out, T value) throws IOException {
if(value == null) {
out.nullValue();
return;
}
out.value(bundle.getString("enum."
+ value.getClass().getSimpleName() + "."
+ value.name()));
}
}
}
和EnumGenerator
的界面:
public interface EnumGenerator {
<T extends Enum<T>> T create(String nextString);
}