2012-04-24 20 views
26

mam ten enum:Gson: Jak zmienić wyjście z Enum

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

    private final int code; 

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

    public int getCode() { 
    return this.code; 
    } 
}; 

i moja prośba klasy, mam tego pola: private RequestStatus status.

Podczas korzystania Gson przekonwertować obiekt Java JSON wynik jest podobny:

"status": "OK" 

Jak mogę zmienić GsonBuilder lub mój Enum obiekt dać mi wyjście jak:

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

Odpowiedz

18

Możesz użyć czegoś takiego:

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

lub bardziej prosto (jak wskazał Jesse Wilson):

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

i

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

@ DennisMadsen Tutaj umieściłem to jako wewnętrzną klasę kodu. Czy tęskniłeś za tym, czy nie rozumiałem twojego pytania? –

+0

Dzięki. Czy możesz dać mi przykład, jak mogę zmienić * JsonWriter * w metodzie zapisu? – dhrm

+0

@DennisMadsen Dodałem przykładowy kod, który według mnie jest tym, czego szukasz. –

2

Oprócz odpowiedzi Polet, o ile trzeba generic Enum serializatora, można to osiągnąć za pomocą refleksji:

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

Zastosowanie:

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

To jest miłe, ale uważaj, zmienia serializatory, a nie pola Enum. –