やりたいこと
Retrofitでは、ステータスコード200の場合はsuccessになりますが、404や422、500の場合はfailureになります。
Api.getUser(id, new Callback<User>() {
@Override
public void success(User user, Response response) {
// ステータスコード200の場合はここ
}
@Override
public void failure(RetrofitError error) {
// ステータスコード404、422、500などのエラーの場合はここ
}
});
ただ、サーバー側でエラーの時に特定のエラーコードやエラーメッセージを返してそれをAndroid側で扱いたいことがあります。
例えば、GitHubのAPIで422を返す時、エラーの内容がjsonで返ってきます。これを扱いたい場合のやり方です。
HTTP/1.1 422 Unprocessable Entity
Content-Length: 149
{
"message": "Validation Failed",
"errors": [
{
"resource": "Issue",
"field": "title",
"code": "missing_field"
}
]
}
getBodyAs()を使う
結論から言うと、 retrofitError.getBodyAs()
を使います。
Api.getUser(id, new Callback<User>() {
@Override
public void success(User user, Response response) {
// 略
}
@Override
public void failure(RetrofitError error) {
// ErrorMessageモデルにパースする
ErrorMessage errorMessage = (ErrorMessage) error.getBodyAs(ErrorMessage.class);
}
});
RetrofitErrorクラスの中をみてみると、Converterを使ってリフレクションしています。これはRetrofitの通常のパースのやり方と同じですね。
RetrofitError.java
public Object getBodyAs(Type type) {
if (response == null) {
return null;
}
TypedInput body = response.getBody();
if (body == null) {
return null;
}
try {
return converter.fromBody(body, type);
} catch (ConversionException e) {
throw new RuntimeException(e);
}
}
以上です。