2012-04-24 9 views
26

Sono questo enum:GSON: Come cambiare l'uscita di Enum

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

    private final int code; 

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

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

e nella mia richiesta di classe, ho questo campo: private RequestStatus status.

Quando si utilizza GSON per convertire l'oggetto Java a JSON il risultato è simile:

"status": "OK" 

Come posso cambiare il mio GsonBuilder o il mio oggetto Enum di darmi un output come:

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

risposta

18

si può usare qualcosa di simile:

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

o più semplicemente (come Jesse Wilson indicato):

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

e

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 Qui lo metto come una classe interna del codice. Ti è mancato o non ho capito la tua domanda? –

+0

Grazie. Puoi darmi un esempio di come posso cambiare * JsonWriter * nel metodo di scrittura? – dhrm

+0

@DennisMadsen Ho aggiunto un codice di esempio che penso sia più o meno quello che stai cercando. –

2

Oltre alla risposta di Polet, se avete bisogno di un serializzatore generica Enum, si può raggiungere attraverso la riflessione:

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

Questo è bello ma attenzione, serializza i getter, non i campi di Enum. –