【问题标题】:Retrofit 2: Handling dynamic JSON response改造 2:处理动态 JSON 响应
【发布时间】:2017-03-27 19:33:11
【问题描述】:

我使用 retrofit 2 作为 REST 客户端,但我不知道如何反序列化 dynamic JSON response

根据状态值(成功或失败),我们的 JSON 在result 字段中可以有两个不同的对象:

  1. 成功的响应返回一个User 对象:

    {
       "status": 200,
       "message": "OK",
       "result": {
          "id": "1",
          "email": "bla@bla.bla"
           ...
       }
    }
    
  2. 失败的响应返回一个Error 对象:

    {
       "status": 100,
       "message": "FAILED",
       "result": {
          "error": "a user with this account email address already exists"
       }
    }
    

我创建了 3 个POJO 类...

  1. API 响应:

    public class APIResponse<T> {
        @Expose private int status;
        @Expose private String message;
        @Expose private T result;
        ...
    }
    
  2. 用户:

    public class User {
        @Expose private String id;
        @Expose private String email;
        ...
    }
    
  3. 错误:

    public class Error {
        @Expose private String error;
        ...
    }
    

这是我拨打电话的方式:

@FormUrlEncoded
@PUT(LOGIN)
Call<APIResponse<User>> login(@Field("email") String email, @Field("password") String password);

这是我得到回应的方式:

@Override
public void onResponse(Call<APIResponse<User>> call, Response<APIResponse<User>> response) {
   ...
}

@Override
public void onFailure(Call<APIResponse<User>> call, Throwable t) {
   ...
}

问题:

API call 期望返回类型为 Call&lt;APIReponse&lt;User&gt;&gt;。但是,它可能无法返回User 对象......那么我该如何修改这种方法以接受APIResponse&lt;User&gt;APIResponse&lt;Error&gt;

换句话说,我如何反序列化两种不同格式的 JSON 数据?

我看过的解决方案:

  1. 在用户类中包含“错误”字段或扩展错误类(丑陋)。
  2. 自定义拦截器或转换器(难以理解)。
  3. 说服 API 开发人员改变它,让我的生活更轻松 :)

【问题讨论】:

  • 为什么你不能尝试使用 volley

标签: android json rest retrofit2


【解决方案1】:

我不确定该解决方案是否可行,但您可以尝试将&lt;APIResponse&lt;User&gt;&gt; 更改为&lt;APIResponse&lt;Object&gt;&gt;

Call<APIResponse<Object>> login(@Field("email") String email, @Field("password") String password);

@Override
   public void onResponse(Call<APIResponse<Object>> call, Response<APIResponse<Object>> response) {
   //depending on the response status, you can cast the object to appropriate class
   Error e = (Error)response.body().getResult();
   //or
   User u = (User)response.body().getResult();
}

或另一种选择,使用 String 而不是 POJO

Call<String> login(@Field("email") String email, @Field("password") String password);

检索 JSON 并手动序列化或使用 GSON

【讨论】:

  • 感谢您的回答。这类似于我们目前正在做的事情,但我希望找到一种更优雅的方式。 JSON 结构似乎需要更改。
【解决方案2】:

您应该检查响应代码并使用所需的类来处理 json

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    • 2020-06-07
    • 2017-06-21
    • 1970-01-01
    • 2017-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多