2017-11-06 17 views
15

Đây là tôi Retrofit dụ:làm việc như thế Polymorphism với Gson (Retrofit)

@Provides 
@Singleton 
ApiManager provideApiManager() { 
    RxJava2CallAdapterFactory rxAdapter = RxJava2CallAdapterFactory.create(); 

    OkHttpClient okHttpClient = new OkHttpClient.Builder() 
      .addNetworkInterceptor(new StethoInterceptor()) 
      .build(); 

    Gson gson = new GsonBuilder().create(); 
    GsonConverterFactory converterFactory = GsonConverterFactory.create(gson); 

    Retrofit retrofit = new Retrofit.Builder() 
      .baseUrl(AppConstants.BASE_URL) 
      .addConverterFactory(converterFactory) 
      .addCallAdapterFactory(rxAdapter) 
      .client(okHttpClient) 
      .build(); 
    return retrofit.create(ApiManager.class); 
} 

mẫu:

class AbstractMessage { 
    String id; 
} 

class TextMessage extends AbstractMessage { 
    String textMessage; 
} 

class ImageMessage extends AbstractMessage { 
    String url; 
    String text; 
} 

Yêu cầu:

@GET("direct/messages") 
Observable<List<AbstractMessage>> getMessages(@Header("Authorization") String authHeader, @Body RequestObject request); 

Thi yêu cầu:

apiManager.getMessages(authHeader, requestObject) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(new Consumer<List<AbstractMessage>>() { 
     @Override 
     public void accept(List<AbstractMessage> messages) throws Exception { 
      ... 
     } 
    }); 

Khi tôi thực hiện yêu cầu, tôi nhận được bộ sưu tập gồm AbstractMessage đối tượng. JSON có thể chứa cả tin nhắn văn bản và hình ảnh. Trong trường hợp của tôi, bộ chuyển đổi JSON sẽ tạo ra AbstractMessage và ánh xạ chỉ trường id. Làm cách nào để tôi chuyển đổi để tạo các đối tượng TextMessageImageMessage ánh xạ tất cả các trường phù hợp và sau đó truyền đến AbstractMessage. Hoặc có thể có một số giải pháp khác.

+2

Tôi không biết Gson, nhưng nếu bạn sử dụng JacksonConverterFactory thay vào đó, bạn có thể sử dụng '@ JsonTypeInfo' để tạo, dựa trên trường phân biệt, một loại hoặc loại khác. Đây là một hướng dẫn tốt: http://www.baeldung.com/jackson-inheritance –

Trả lời

17

Bạn phải tạo một RuntimeTypeAdapterFactory cho các đối tượng AbstractMessage, TextMessage và ImageMessage và sau đó bạn phải đặt nó vào trường hợp gson.

Giả sử rằng bạn có những đối tượng:

public class Animal { 
    protected String name; 
    protected String type; 

    public Animal(String name, String type) { 
     this.name = name; 
     this.type = type; 
    } 
} 

public class Dog extends Animal { 
    private boolean playsCatch; 

    public Dog(String name, boolean playsCatch) { 
     super(name, "dog"); 
     this.playsCatch = playsCatch; 
    } 
} 

public class Cat extends Animal { 
    private boolean chasesLaser; 

    public Cat(String name, boolean chasesLaser) { 
     super(name, "cat"); 
     this.chasesLaser = chasesLaser; 
    } 
} 

này dưới đây là RuntimeTypeAdapter mà bạn cần để deserialize (và serialize) một cách chính xác các đối tượng:

RuntimeTypeAdapterFactory<Animal> runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory 
    .of(Animal.class, "type") 
    .registerSubtype(Dog.class, "dog") 
    .registerSubtype(Cat.class, "cat"); 

Gson gson = new GsonBuilder() 
    .registerTypeAdapterFactory(runtimeTypeAdapterFactory) 
    .create(); 

Lớp RuntimeTypeAdapterFactory.java không được gửi kèm với gói Gson, vì vậy bạn phải tải xuống và thêm nó theo cách thủ công vào dự án của bạn.

Bạn có thể đọc thêm về adapter runtime herehere

Xin lưu ý rằng tiêu đề của câu hỏi của bạn nên được "Polymorphism với Gson"

Tôi hy vọng nó giúp.

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