Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多态性如何与Gson一起工作(改装)_Java_Android_Json_Gson_Retrofit - Fatal编程技术网

Java 多态性如何与Gson一起工作(改装)

Java 多态性如何与Gson一起工作(改装),java,android,json,gson,retrofit,Java,Android,Json,Gson,Retrofit,这是我的改装实例: @Provides @Singleton ApiManager provideApiManager() { RxJava2CallAdapterFactory rxAdapter = RxJava2CallAdapterFactory.create(); OkHttpClient okHttpClient = new OkHttpClient.Builder() .addNetworkInterceptor(new StethoInt

这是我的
改装
实例:

@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);
}
型号:

class AbstractMessage {
    String id;
}

class TextMessage extends AbstractMessage {
    String textMessage;
}

class ImageMessage extends AbstractMessage {
    String url;
    String text;
}
请求:

@GET("direct/messages")
Observable<List<AbstractMessage>> getMessages(@Header("Authorization") String authHeader, @Body RequestObject request);   
@GET(“直接/消息”)
可观察的getMessages(@Header(“Authorization”)字符串authHeader,@Body RequestObject request);
执行请求:

apiManager.getMessages(authHeader, requestObject)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Consumer<List<AbstractMessage>>() {
        @Override
        public void accept(List<AbstractMessage> messages) throws Exception {
            ...
        }
    });
apimager.getMessages(authHeader,requestObject) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .订阅(新消费者){ @凌驾 公共void接受(列表消息)引发异常{ ... } }); 当我执行一个请求时,我会收到一组
AbstractMessage
对象。
JSON
可以包含文本和图像消息。在我的例子中,
JSON
converter创建
AbstractMessage
并只映射
id
字段。如何使转换器创建
TextMessage
ImageMessage
对象映射所有匹配字段,然后将其强制转换为
AbstractMessage
。或者还有其他解决方案。

您必须为AbstractMessage、TextMessage和ImageMessage创建一个对象,然后必须将其设置到gson实例中

假设您拥有这些对象:

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;
    }
}
RuntimeTypeAdapterFactory<Animal> runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory
    .of(Animal.class, "type")
    .registerSubtype(Dog.class, "dog")
    .registerSubtype(Cat.class, "cat");

Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(runtimeTypeAdapterFactory)
    .create();
下面是正确反序列化(和序列化)这些对象所需的RuntimeTypeAdapter:

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;
    }
}
RuntimeTypeAdapterFactory<Animal> runtimeTypeAdapterFactory = RuntimeTypeAdapterFactory
    .of(Animal.class, "type")
    .registerSubtype(Dog.class, "dog")
    .registerSubtype(Cat.class, "cat");

Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(runtimeTypeAdapterFactory)
    .create();
RuntimeTypeAdapterFactory未随Gson软件包一起提供,因此您必须手动下载它

您可以阅读有关运行时适配器和

请注意,您的问题标题应为“Gson多态性”


我希望它能有所帮助。

我不知道Gson,但如果您使用JacksonConverterFactory,您可以使用
@JsonTypeInfo
基于鉴别器字段创建一种或另一种类型。这是一个很好的教程: