Gson: How to change output of Enum

匿名 (未验证) 提交于 2019-12-03 01:26:01

问题:

I've this enum:

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

and in my Request-class, I have this field: private RequestStatus status.

When using Gson to convert the Java object to JSON the result is like:

"status": "OK"

How can I change my GsonBuilder or my Enum object to give me an output like:

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

回答1:

You can use something like this:

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

or more simply (as Jesse Wilson indicated):

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

and

public class MyEnumAdapterFactory implements TypeAdapterFactory {      @Override     public  TypeAdapter create(final Gson gson, final TypeToken type) {             Class super T> 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;          }     }  }


回答2:

In addition to Polet's answer, if you need a generic Enum serializer, you can achieve it via reflection:

public class EnumAdapterFactory implements TypeAdapterFactory {      @Override     public  TypeAdapter create(final Gson gson, final TypeToken type)     {         Class super T> 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;         }     } }

Usage:

@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)); }


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!