android - 如何制作Retrofit类

标签 android json retrofit

我正在尝试使用 retrofitRiot API 发出 api 请求的库 示例请求返回如下所示的 json:

{"dyrus":{"id":5908,"name":"Dyrus","profileIconId":752,"summonerLevel":30,"revisionDate":1431126576000}}

注意对象dyrus有多个子属性,我想获取id属性。我遇到的问题是我不想只查找 dyrus 的 id,也不想查找其他玩家的 id。当我查找其他玩家时,对象的名称会根据我查找的名称而变化。例如,这是另一个示例请求:

{"theoddone":{"id":60783,"name":"TheOddOne","profileIconId":752,"summonerLevel":30,"revisionDate":1431327360000}}

theoddone 现在是对象的名称。如何制作一个改进类,根据被搜索的人动态更改对象的名称。或者如何访问 id 属性?我的类(class)现在看起来像这样,但不起作用:

public class Summoner {

    private int id;
    private String name;
    private int profileIconId;
    private int summonerLevel;
    private int revisionDate;

    /**
     *
     * @return
     * The id
     */
    public int getId() {
        return id;
    }

    /**
     *
     * @param id
     * The id
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     *
     * @return
     * The name
     */
    public String getName() {
        return name;
    }

    /**
     *
     * @param name
     * The name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     *
     * @return
     * The profileIconId
     */
    public int getProfileIconId() {
        return profileIconId;
    }

    /**
     *
     * @param profileIconId
     * The profileIconId
     */
    public void setProfileIconId(int profileIconId) {
        this.profileIconId = profileIconId;
    }

    /**
     *
     * @return
     * The summonerLevel
     */
    public int getSummonerLevel() {
        return summonerLevel;
    }

    /**
     *
     * @param summonerLevel
     * The summonerLevel
     */
    public void setSummonerLevel(int summonerLevel) {
        this.summonerLevel = summonerLevel;
    }

    /**
     *
     * @return
     * The revisionDate
     */
    public int getRevisionDate() {
        return revisionDate;
    }

    /**
     *
     * @param revisionDate
     * The revisionDate
     */
    public void setRevisionDate(int revisionDate) {
        this.revisionDate = revisionDate;
    }
}

如果您需要查看我如何使用改造的任何其他部分,请告诉我。提前致谢。

界面:

public interface SummonerId {

    @GET("/api/lol/{region}/v1.4/summoner/by-name/{summonerName}")
    void summoner(
      @Path("region") String region,
      @Path("summonerName") String summonerName,
      @Query("api_key") String apiKey,
      Callback<Summoner> cb
    );

}

我的 Activity 的 oncreate 方法中的代码:

RestAdapter restAdapter = new RestAdapter.Builder()
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .setEndpoint("https://na.api.pvp.net")
            .build();

SummonerId service = restAdapter.create(SummonerId.class);

service.summoner("na", "dyrus", "MY API KEY", new Callback<Summoner>() {
    @Override
    public void success(Summoner summoner, Response response) {
        //summoner.getId() == null
    }

    @Override
    public void failure(RetrofitError error) {

    }
});

当我运行代码时,它成功连接到服务器并获取正确的 json,但没有正确地将其放入类中。

最佳答案

好的,我明白了。不过花了我很长时间。

因此,首先您必须创建一个自定义 TypeAdapterFactory,如下所示:

public class ItemTypeAdapterFactory implements TypeAdapterFactory {

    String name;

    public ItemTypeAdapterFactory(String name) {
        this.name = name;
    }

    public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {

        final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
        final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);

        return new TypeAdapter<T>() {

            public void write(JsonWriter out, T value) throws IOException {
                delegate.write(out, value);
            }

            public T read(JsonReader in) throws IOException {

                JsonElement jsonElement = elementAdapter.read(in);
                if (jsonElement.isJsonObject()) {
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    if (jsonObject.has(name) && jsonObject.get(name).isJsonObject())
                    {
                        jsonElement = jsonObject.get(name);
                    }
                }

                return delegate.fromJsonTree(jsonElement);
            }
        }.nullSafe();
    }
}

对于您的使用,您实际上可以复制并粘贴它,但请尝试并了解会发生什么。

接下来,您必须实现一个自定义 GsonBuilder,如下所示:

Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ItemTypeAdapterFactory("dyrus")).create();

重要的部分是“dyrus”,您可以将其替换为您要查找的名称。

接下来将 gsonbuilder 添加到您的重新适配器:

RestAdapter restAdapter = new RestAdapter.Builder()
                    .setEndpoint("your endpoint")
                    .setConverter(new GsonConverter(gson))
                    .build();

在连接界面中使用以下方法:

public void getCurrentUser(Callback<Summoner> response);

并接收您的 POJO 响应,如下所示:

    ConnectionInterface connectionInterface = restAdapter.create(**ConnectionInterface.class**);
    connectionInterface.getCurrentUser(new Callback<Summoner>() {
        @Override
        public void success(Summoner response, Response response2) {
        }

        @Override
        public void failure(RetrofitError error) {
            Log.e("Response", error.getLocalizedMessage().toString());
        }
    });
}

};

您的 POJO 类是正确的,您可以将其命名为任何您想要的名称,只要变量保留其名称即可。为了清楚起见,您可以调用类 UserPOJO,并将 Summoner 的所有实例重命名为 UserPojo

希望这有帮助!

关于android - 如何制作Retrofit类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30172289/

相关文章:

android - 将 I18n Iphone 文件转换为 Android

android - 使用 Google 云打印从应用程序打印到餐厅的指定打印机

c# - 从 C# 中的 json 文件访问单个值

android - 改造:如何在请求中指定以逗号分隔的参数?

android - Android 应用程序的最大大小

java - textview 上的 onclick 事件(具有 TextIsSelectable ="true")仅在第二次单击时调用

javascript - 分配从对象列表生成的标签值列表

ios - 在 iOS Swift 中解析 JSON 格式的最佳方法是什么?

android - 专门使用 GraphQl 解析 JSON 数据

android - 处理异步调用改造中的未授权错误