因此,您从同一端点有两个不同的成功响应(状态码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())
}})
}