Gson: How to change output of Enum

前端 未结 2 2003
無奈伤痛
無奈伤痛 2020-12-24 13:14

I\'ve this enum:

enum RequestStatus {
  OK(200), NOT_FOUND(400);

  private final int code;

  RequestStatus(int code) {
    this.code = code;
  }

         


        
相关标签:
2条回答
  • 2020-12-24 14:05

    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 <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
                Class<? super T> rawType = type.getRawType();
                if (rawType == RequestStatus.class) {
                    return new MyEnumTypeAdapter<T>();
                }
                return null;
        }
    
        public class MyEnumTypeAdapter<T> extends TypeAdapter<T> {
    
             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;
             }
        }
    
    }
    
    0 讨论(0)
  • 2020-12-24 14:05

    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 <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type)
        {
            Class<? super T> rawType = type.getRawType();
            if (rawType.isEnum())
            {
                return new EnumTypeAdapter<T>();
            }
            return null;
        }
    
        public class EnumTypeAdapter<T> extends TypeAdapter<T>
        {
            @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<ReportTypes> 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));
    }
    
    0 讨论(0)
提交回复
热议问题