Gson:如何改变Enum的输出

我有这个枚举

enum RequestStatus { OK(200), NOT_FOUND(400); private final int code; RequestStatus(int code) { this.code = code; } public int getCode() { return this.code; } }; 

在我的Request-class中,我有这个字段: private RequestStatus status

使用Gson将Java对象转换为JSON时,结果如下:

 "status": "OK" 

如何更改我的GsonBuilder或我的Enum对象,为我提供如下输出:

 "status": { "value" : "OK", "code" : 200 } 

你可以使用这样的东西:

 GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapterFactory(new MyEnumAdapterFactory()); 

或者更简单(正如Jesse Wilson所说):

 GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(RequestStatus.class, new MyEnumTypeAdapter()); 

 public class MyEnumAdapterFactory implements TypeAdapterFactory { @Override public  TypeAdapter create(final Gson gson, final TypeToken type) { Class rawType = type.getRawType(); if (rawType == RequestStatus.class) { return new MyEnumTypeAdapter(); } return null; } public class MyEnumTypeAdapter extends TypeAdapter { public void write(JsonWriter out, T value) throws IOException { if (value == null) { out.nullValue(); return; } RequestStatus status = (RequestStatus) value; // Here write what you want to the JsonWriter. out.beginObject(); out.name("value"); out.value(status.name()); out.name("code"); out.value(status.getCode()); out.endObject(); } public T read(JsonReader in) throws IOException { // Properly deserialize the input (if you use deserialization) return null; } } } 

除了Polet的答案,如果你需要一个通用的Enum序列化器 ,你可以通过reflection实现它:

 public class EnumAdapterFactory implements TypeAdapterFactory { @Override public  TypeAdapter create(final Gson gson, final TypeToken type) { Class rawType = type.getRawType(); if (rawType.isEnum()) { return new EnumTypeAdapter(); } return null; } public class EnumTypeAdapter extends TypeAdapter { @Override public void write(JsonWriter out, T value) throws IOException { if (value == null || !value.getClass().isEnum()) { out.nullValue(); return; } try { out.beginObject(); out.name("value"); out.value(value.toString()); Arrays.stream(Introspector.getBeanInfo(value.getClass()).getPropertyDescriptors()) .filter(pd -> pd.getReadMethod() != null && !"class".equals(pd.getName()) && !"declaringClass".equals(pd.getName())) .forEach(pd -> { try { out.name(pd.getName()); out.value(String.valueOf(pd.getReadMethod().invoke(value))); } catch (IllegalAccessException | InvocationTargetException | IOException e) { e.printStackTrace(); } }); out.endObject(); } catch (IntrospectionException e) { e.printStackTrace(); } } public T read(JsonReader in) throws IOException { // Properly deserialize the input (if you use deserialization) return null; } } } 

用法:

 @Test public void testEnumGsonSerialization() { List testEnums = Arrays.asList(YourEnum.VALUE1, YourEnum.VALUE2); GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapterFactory(new EnumAdapterFactory()); Gson gson = builder.create(); System.out.println(gson.toJson(reportTypes)); }