改造方法返回通配符 [英] Retrofit method return wildcard

查看:18
本文介绍了改造方法返回通配符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 API 响应,旨在为我们的应用程序的各种活动一般返回数据.为了使应用程序尽可能通用和灵活,我们设置了一个 API 来提供一组 URL,用于在我们的活动中创建各种行.我们的基础对象看起来像:

I have an API response which is meant to generically return data for various activities of our application. In an effort to make the application as generic and flexible as possible we have setup an API to deliver a collection of URLs to utilize to create various rows on our activities. Our base object looks like:

public class BaseApiObject {

    @SerializedName("apiVersion")
    private String apiVersion = null;
    @SerializedName("totalResults")
    private Integer totalResults = null;
}

我们对活动的回应如下:

Our response for the activity looks like:

public class ActivityApiResponse extends BaseApiObject {
    @SerializedName("results")
    private List<ScreenItem> results = new ArrayList<>();
}

并且 ScreenItem 看起来像:

And the ScreenItem looks like:

public class ScreenItem extends BaseApiObject {
     @SerializedName("apiUrls")
     private List<String> apiUrls = new ArrayList<>() ;
}

我希望能够通过改造来做这样的事情:

I would like to be able to do something like this with retrofit:

@GET("{url}")
Call<? extends BaseApiObject> getUrl(@Path("url") String url);

我们知道我们发出的每个请求都将返回一个 BaseApiObject,但我们不确定我们将实际返回哪种类型的对象——其中一些 URL 将返回许多不同类型对象的列表.

We know that each request we make will return a BaseApiObject, but we are unsure of which type of object we will actually return -- and some of these URLs will return a list of many different types of objects.

我们收到以下错误:

java.lang.IllegalArgumentException: Method return type must not include a type variable or wildcard: retrofit2.Call<? extends com.company.BaseApiObject>

Retrofit 有没有办法处理这种情况,还是我需要返回 BaseApiObject,然后使用自定义 gson 反序列化器来实际返回正确的对象类型?

Is there a way with Retrofit to handle this scenario or do I need to return the BaseApiObject, and then use a custom gson deserializer to actually return the proper object type(s)?

推荐答案

最后,我最终需要创建自己的解串器.我采用了 JsonDeserializationContext,然后根据 json 响应中返回的类型解析了我的元素.

In the end, I ended up needing to create my own Deserializer. I took the JsonDeserializationContext and then parsed my elements based on the type which was returned in the json response.

例如假设我的 json 看起来像:

For instance assume my json looked like:

{ "shapes": 
  [ 
    {"type": "circle", "radius": 2},
    {"type": "rectangle", "width": 3, "height": 2},
    {"type": "triangle", "sides": [3, 4, 5]}
  ],
  "apiVersion": "0.1.0",
  "totalResults": "3"
}

在我的解串器中,我会查看循环中形状的类型,然后执行以下操作:

In my deserializer, I would look at the type of the shapes in a loop, and do something like:

switch(jsonObject.get("type").getAsString()) {
    case "circle":
        return context.deserialize(jsonObject, Circle.class);
        break;

    case "rectangle": 
        return context.deserialize(jsonObject, Rectangle.class);
        break;

    case "triangle":
        return context.deserialize(jsonObject, Triangle.class);
        break;

    default:
        return context.deserialize(jsonObject, Shape.class);
        break; 
}

这篇关于改造方法返回通配符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆