Ste*_*eve 28 java gson json-deserialization
我有一个枚举:
enum Type {
LIVE, UPCOMING, REPLAY
}
Run Code Online (Sandbox Code Playgroud)
还有一些JSON:
{
"type": "live"
}
Run Code Online (Sandbox Code Playgroud)
一节课:
class Event {
Type type;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试反序列化JSON的,使用GSON,我收到null的Event类型字段,因为在JSON类型字段的情况下,不匹配的枚举.
Events events = new Gson().fromJson(json, Event.class);
Run Code Online (Sandbox Code Playgroud)
如果我将枚举更改为以下,那么一切正常:
enum Type {
live, upcoming, replay
}
Run Code Online (Sandbox Code Playgroud)
但是,我想将枚举常量保留为全部大写.
我假设我需要编写一个适配器,但没有找到任何好的文档或示例.
什么是最好的解决方案?
编辑:
我能够让JsonDeserializer工作.有没有更通用的方法来编写这个,因为每次枚举值和JSON字符串之间的情况不匹配时都必须编写它.
protected static class TypeCaseInsensitiveEnumAdapter implements JsonDeserializer<Type> {
@Override
public Type deserialize(JsonElement json, java.lang.reflect.Type classOfT, JsonDeserializationContext context)
throws JsonParseException {
return Type.valueOf(json.getAsString().toUpperCase());
}
}
Run Code Online (Sandbox Code Playgroud)
pro*_*aea 91
我发现(刚才)这样做的一种更简单的方法是使用@SerializedName注释.我在EnumTest.java这里找到了它(Genderln 195周围的类):
这假设您的所有类型都将以小写形式出现而不是"不区分大小写"
public enum Type {
@SerializedName("live")
LIVE,
@SerializedName("upcoming")
UPCOMING,
@SerializedName("replay")
REPLAY;
}
Run Code Online (Sandbox Code Playgroud)
这是我发现的最简单,最通用的方法.希望它能帮到你.
Jes*_*son 20
方便地使用,这非常接近TypeAdapterFactory的Javadoc中给出的示例:
public class CaseInsensitiveEnumTypeAdapterFactory implements TypeAdapterFactory {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
Class<T> rawType = (Class<T>) type.getRawType();
if (!rawType.isEnum()) {
return null;
}
final Map<String, T> lowercaseToConstant = new HashMap<String, T>();
for (T constant : rawType.getEnumConstants()) {
lowercaseToConstant.put(toLowercase(constant), constant);
}
return new TypeAdapter<T>() {
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(toLowercase(value));
}
}
public T read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
} else {
return lowercaseToConstant.get(toLowercase(reader.nextString()));
}
}
};
}
private String toLowercase(Object o) {
return o.toString().toLowerCase(Locale.US);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 11
这是一个相当古老的问题,但接受的答案对我不起作用,并且使用@SerializedName是不够的,因为我想确保我可以匹配@SerializedName,"value"并且"Value".
我设法根据问题中发布的代码制作通用适配器:
public class UppercaseEnumAdapter implements JsonDeserializer<Enum> {
@Override
public Enum deserialize(JsonElement json, java.lang.reflect.Type type, JsonDeserializationContext context)
throws JsonParseException {
try {
if(type instanceof Class && ((Class<?>) type).isEnum())
return Enum.valueOf((Class<Enum>) type, json.getAsString().toUpperCase());
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(MyEnum.class, new UppercaseEnumAdapter());
Gson gson = gsonBuilder.create();
Run Code Online (Sandbox Code Playgroud)
Blu*_*rer 11
现在,您可以为@SerializedName添加多个值,如下所示:
public enum Type {
@SerializedName(value = "live", alternate = {"LIVE"})
LIVE,
@SerializedName(value = "upcoming", alternate = {"UPCOMING"})
UPCOMING,
@SerializedName(value = "replay", alternate = {"REPLAY"})
REPLAY;
}
Run Code Online (Sandbox Code Playgroud)
我觉得你有点晚了,但我希望它会对其他人有所帮助!
| 归档时间: |
|
| 查看次数: |
12481 次 |
| 最近记录: |