我需要使用Gson输出枚举值,因为客户端限制需要小写。
例如CLOSE_FILE
为close_file
。
有一种简单的方法吗?我已经看过创建一个实现JsonSerializer
的类,但看起来我必须手动序列化整个类(这很复杂)是这样的吗?
答案 0 :(得分:18)
如果您可以控制enum
类型,请使用@SerializedName
为其成员添加注释,并为其指定相应的序列化值。例如,
enum Action {
@SerializedName("close_file")
CLOSE_FILE;
}
如果您无法控制enum
,请在创建TypeAdapter
实例时提供自定义Gson
。例如,
Gson gson = new GsonBuilder().registerTypeAdapter(Action.class, new TypeAdapter<Action>() {
@Override
public void write(JsonWriter out, Action value) throws IOException {
out.value(value.name().toLowerCase());
}
@Override
public Action read(JsonReader in) throws IOException {
return Action.valueOf(in.nextString().toUpperCase());
}
}).create();
答案 1 :(得分:0)
如果要将所有枚举序列化为小写,可以使用此代码
Gson gson = new GsonBuilder().registerTypeHierarchyAdapter(Enum.class, new EnumToLowerCaseJsonConverter()).create();
public final class EnumToLowerCaseJsonConverter implements JsonSerializer<Enum<?>>, JsonDeserializer<Enum<?>> {
private static Map<String, Class<? extends Enum<?>>> typesToClass = new HashMap<>();
@Override
public JsonElement serialize(final Enum<?> src, final Type typeOfSrc,
final JsonSerializationContext context) {
if (src == null) {
return JsonNull.INSTANCE;
}
return new JsonPrimitive(src.name().toLowerCase());
}
@SuppressWarnings("unchecked")
@Override
public Enum<?> deserialize(final JsonElement json, final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
if (json == null || json.isJsonNull()) {
return null;
}
if (!json.isJsonPrimitive() || !json.getAsJsonPrimitive().isString()) {
throw new JsonParseException(
"Expecting a String JsonPrimitive, getting " + json.toString());
}
try {
final String enumClassName = typeOfT.getTypeName();
Class<? extends Enum<?>> clazz = typesToClass.get(enumClassName);
if (clazz == null) {
clazz = (Class<? extends Enum<?>>) Class.forName(enumClassName);
typesToClass.put(enumClassName, clazz);
}
return Enum.valueOf((Class) clazz, json.getAsString().toUpperCase());
} catch (final ClassNotFoundException e) {
throw new JsonParseException(e);
}
}
}
答案 2 :(得分:0)
易于使用的特定类型适配器:
Gson gson = new GsonBuilder().registerTypeAdapter(Action.class, new EnumToLowerCaseTypeAdapter<>(Action.class)).create();
public final class EnumToLowerCaseTypeAdapter<T extends Enum<?>> extends TypeAdapter<T> {
private final Class<T> clazz;
public EnumToLowerCaseTypeAdapter(final Class<T> clazz) {
this.clazz = clazz;
}
@Override
public void write(final JsonWriter out, final T value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(value.name().toLowerCase());
}
}
@SuppressWarnings("unchecked")
@Override
public T read(final JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
final String value = in.nextString();
return (T) Enum.valueOf((Class) clazz, value.toUpperCase());
}
}
}