2012-08-23 33 views
11

phép nói rằng tôi có các lớp sau:Gson tự động thêm classname

public class Dog { 
    public String name = "Edvard"; 
} 

public class Animal { 
    public Dog madDog = new Dog(); 
} 

Nếu tôi chạy này trough một Gson nó sẽ serialize nó như sau:

GSon gson = new GSon(); 
String json = gson.toJson(new Animal()) 

result: 
{ 
    "madDog" : { 
     "name":"Edvard" 
    } 
} 

này đến nay rất tốt, nhưng tôi muốn thêm className cho tất cả các lớp tự động với Gson, vì vậy tôi nhận được kết quả sau:

{ 
    "madDog" : { 
     "name":"Edvard", 
     "className":"Dog" 
    }, 
    "className" : "Animal" 
} 

Có ai biết nếu điều này là có thể với một số loại interceptors hoặc một cái gì đó với Gson?

Trả lời

3

Bạn sẽ cần serializers tùy chỉnh cho việc này. Dưới đây là một ví dụ cho các lớp động vật trên:

public class AnimalSerializer implements JsonSerializer<Animal> { 
    public JsonElement serialize(Animal animal, Type typeOfSrc, JsonSerializationContext context) { 
     JsonObject jo = new JsonObject(); 

     jo.addProperty("className", animal.getClass().getName()); 
     // or simply just 
     jo.addProperty("className", "Animal"); 

     // Loop through the animal object's member variables and add them to the JO accordingly 

     return jo; 
    } 
} 

Sau đó, bạn cần phải nhanh chóng một Gson mới() đối tượng qua GsonBuilder vì lợi ích của gắn serializers như mong muốn:

Gson gson = new GsonBuilder() 
    .registerTypeAdapter(Dog.class, new DogSerializer()) 
    .registerTypeAdapter(Animal.class, new AnimalSerializer()) 
    .create(); 
+1

Điều này thực sự không giải quyết được sự cố? Tôi muốn sử dụng serialization tiêu chuẩn cho tất cả các lĩnh vực nhưng thêm một trường bổ sung duy nhất cho tên lớp - nó cảm thấy giống như một trường hợp sử dụng thực sự bình thường. – mjaggard

+0

Vấn đề là bạn muốn thêm một trường đơn vào tuần tự hóa bình thường và giải pháp của tôi giải quyết vấn đề đó (đặc biệt là không phụ thuộc vào bất kỳ phụ thuộc bổ sung nào). Tôi hiểu rằng đó là một loại đau đớn nhưng ra khỏi hộp không có/không có vẻ là một cách để đạt được nhiệm vụ đơn giản này mà không cần tạo và đăng ký serializers tùy chỉnh. –

14

Hãy nhìn vào này: http://code.google.com/p/google-gson/source/browse/trunk/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java

RuntimeTypeAdapterFactory<BillingInstrument> rta = RuntimeTypeAdapterFactory.of(
    BillingInstrument.class) 
    .registerSubtype(CreditCard.class); 
Gson gson = new GsonBuilder() 
    .registerTypeAdapterFactory(rta) 
    .create(); 

CreditCard original = new CreditCard("Jesse", 234); 
assertEquals("{\"type\":\"CreditCard\",\"cvv\":234,\"ownerName\":\"Jesse\"}", 
    gson.toJson(original, BillingInstrument.class)); 
+1

Đây chính xác là những gì tôi cần! Lớp đó không có trong Gson. Tôi có cần phải bao gồm RuntimeTypeAdapterFactory.java trong cơ sở mã của tôi không? Hay có cách nào đó để làm nó như một thư viện? – paj28

+1

Vâng, bạn cần phải thêm nó vào mã của bạn. –

+0

Điều này cũng được xuất bản ngay bây giờ: https://mvnrepository.com/artifact/org.danilopianini/gson-extras/0.1.0 – pandaadb

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