2012-04-24 19 views
26

Tôi đã enum này:Gson: Làm thế nào để thay đổi sản lượng của Enum

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

    private final int code; 

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

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

và trong Request-lớp học của tôi, tôi có lĩnh vực này: private RequestStatus status.

Khi sử dụng Gson để chuyển đổi đối tượng Java để JSON kết quả là như sau:

"status": "OK" 

Làm thế nào tôi có thể thay đổi GsonBuilder tôi hoặc đối tượng Enum của tôi để cho tôi một đầu ra như:

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

Trả lời

18

Bạn có thể sử dụng một cái gì đó như thế này:

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

hoặc đơn giản hơn (như Jesse Wilson đã nêu):

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

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 Ở đây tôi đặt nó như là một lớp bên trong của mã. Bạn đã bỏ lỡ nó hay tôi không hiểu câu hỏi của bạn? –

+0

Cảm ơn. Bạn có thể cho tôi một ví dụ về, làm thế nào tôi có thể thay đổi * JsonWriter * trong phương pháp ghi? – dhrm

+0

@DennisMadsen Tôi đã thêm một số mã mẫu mà tôi nghĩ là khá nhiều những gì bạn đang tìm kiếm. –

2

Ngoài câu trả lời Polet, nếu bạn cần một serializer generic Enum, bạn có thể đạt được điều đó thông qua phản ánh:

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

Cách sử dụng:

@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

Điều này là tốt đẹp nhưng xem ra, nó serializes getters, không phải lĩnh vực của Enum. –

Các vấn đề liên quan