您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Retrofit2处理状态码为200但json结构与datamodel类不同时的条件

Retrofit2处理状态码为200但json结构与datamodel类不同时的条件

因此,您从同一端点有两个不同的成功响应(状态码200)。一个是实际的数据模型,另一个错误(都像这样的json结构?:

有效的LoginBean响应:

{
  "id": 1234,
  "something": "something"
}

错误回应

{
  "error": "error message"
}

您可以做的是拥有一个包装两种情况并使用自定义反序列化器的实体。

class LoginBeanResponse {
  @Nullable private final LoginBean loginBean;
  @Nullable private final ErrorMessage errorMessage;

  LoginBeanResponse(@Nullable LoginBean loginBean, @Nullable ErrorMessage errorMessage) {
    this.loginBean = loginBean;
    this.errorMessage = errorMessage;
  }
  // Add getters and whatever you need
}

错误的包装器:

class ErrorMessage {
  String errorMessage;
  // And whatever else you need
  // ...
}

然后,您需要一个JsonDeserializer

public class LoginBeanResponseDeserializer implements JsonDeserializer<LoginBeanResponse> {

  @Override
  public LoginBeanResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

    // Based on the structure you check if the data is valid or not
    // Example for the above defined structures:

    // Get JsonObject
    final JsonObject jsonObject = json.getAsJsonObject();
    if (jsonObject.has("error") {
      ErrorMessage errorMessage = new Gson().fromJson(jsonObject, ErrorMessage.class);
      return new LoginBeanResponse(null, errorMessage)
    } else {
      LoginBean loginBean = new Gson().fromJson(jsonObject, LoginBean.class):
      return new LoginBeanResponse(loginBean, null);
    }
  }
}

然后将此反序列化器添加到中GsonConverterFactory

GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(LoginBeanResponse.class, new LoginBeanResponseDeserializer()).create():

apiClient = new Retrofit.Builder()
    .baseUrl(url)
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .addConverterFactory(GsonConverterFactory.create(gsonBuilder))
    .client(httpClient)
    .build();

这是我可以想到的唯一方法。但是,正如已经提到的,这种API设计是错误的,因为存在状态代码是有原因的。我仍然希望这会有所帮助。

编辑:然后,您可以在调用Retrofit的类中做什么(如果您已经使用RxJava 从转换Call<LoginBeanResponse>Single<LoginBeanResponse>)实际上返回了正确的错误。就像是:

Single<LoginBean> getLoginResponse(Map<String, String> queryMap) {
    restApi.getLoginResponse(queryMap)
        .map(loginBeanResponse -> { if(loginBeanResponse.isError()) {
            Single.error(new Throwable(loginBeanResponse.getError().getErrorMessage()))
        } else { 
            Single.just(loginBeanReponse.getLoginBean()) 
        }})
}
其他 2022/1/1 18:32:05 有502人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶