因此,当我对服务器进行 POST API 调用时,我收到带有 JSON 响应的 400 Bad Request 错误。
{
"userMessage": "Blah",
"internalMessage": "Bad Request blah blah",
"errorCode": 1
}
我称之为
Call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//AA
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
//BB
}
}
但是问题是,一旦我收到响应,就会调用 onFailure() 以便调用 //BB 。在这里,我无法访问 JSON 响应。 当我记录 api 请求和响应时,它根本不显示 JSON 响应。 Throwable t 是 IOException。然而,奇怪的是,当我对 Postman 进行相同的调用时,它确实返回了预期的 JSON 响应以及 400 错误代码。
所以我的问题是当我收到 400 Bad Request 错误时如何获得 json 响应?我应该向 okhttpclient 添加一些东西吗?
谢谢
您可以在
onResponse
方法中执行此操作,请记住 400 是响应状态而不是错误:
if (response.code() == 400) {
Log.v("Error code 400",response.errorBody().string());
}
您可以使用 Gson
处理任何响应代码
除了 200-300:
if (response.code() == 400) {
Gson gson = new GsonBuilder().create();
ErrorPojoClass mError=new ErrorPojoClass();
try {
mError= gson.fromJson(response.errorBody().string(),ErrorPojoClass.class);
Toast.makeText(context, mError.getDescription(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
// handle failure to read error
}
}
将此添加到您的
build.gradle
:compile 'com.google.code.gson:gson:2.7'
如果您想创建
Pojo
类,请转到 Json Schema 2 Pojo 并粘贴您的示例 Json
响应。选择源类型 Json 和注释 Gson .
您可以尝试以下代码来获得 400 响应。您可以从 errorBody() 方法获取错误响应。
Call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//get success and error response here
if (response.code() == 400) {
if(!response.isSuccessful()) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response.errorBody().string());
String userMessage = jsonObject.getString("userMessage");
String internalMessage = jsonObject.getString("internalMessage");
String errorCode = jsonObject.getString("errorCode");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
//get failure response here
}
}
}
编辑: 将方法名称从
toString
修复为 string
使用类对象处理 ErrorResponse
科特林
val errorResponse = Gson().fromJson(response.errorBody()!!.charStream(), ErrorResponse::class.java)
Java
ErrorResponse errorResponse = new Gson().fromJson(response.errorBody.charStream(),ErrorResponse.class)
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
DialogHelper.dismiss();
if (response.isSuccessful()) {
// Success
} else {
try {
JSONObject jObjError = new JSONObject(response.errorBody().string());
Toast.makeText(getContext(), jObjError.getString("message"), Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
第一步:
创建用于错误响应的 POJO 类。就我而言,ApiError.java
public class ApiError {
@SerializedName("errorMessage")
@Expose
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage= errorMessage;
}
}
第二步:
在您的 api 回调中写入以下代码。
Call.enqueue(new Callback<RegistrationResponse>() {
@Override
public void onResponse(Call<RegistrationResponse> call, Response<RegistrationResponse> response)
{
if (response.isSuccessful()) {
// do your code here
} else if (response.code() == 400) {
Converter<ResponseBody, ApiError> converter =
ApiClient.retrofit.responseBodyConverter(ApiError.class, new Annotation[0]);
ApiError error;
try {
error = converter.convert(response.errorBody());
Log.e("error message", error.getErrorMessage());
Toast.makeText(context, error.getErrorMessage(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<RegistrationResponse> call, Throwable t) {
//do your failure handling code here
}
}
这里
ApiClient.retrofit
是您的静态改造实例。
public static <T> Observable<T> rxified(final Call<T> request, final Class<T> klazz) {
return Observable.create(new ObservableOnSubscribe<T>() {
AtomicBoolean justDisposed = new AtomicBoolean(false);
@Override
public void subscribe(final ObservableEmitter<T> emitter) throws Exception {
emitter.setDisposable(new Disposable() {
@Override
public void dispose() {
request.cancel();
justDisposed.set(true);
}
@Override
public boolean isDisposed() {
return justDisposed.get();
}
});
if (!emitter.isDisposed())
request.enqueue(new Callback<T>() {
@Override
public void onResponse(Call<T> call, retrofit2.Response<T> response) {
if (!emitter.isDisposed()) {
if (response.isSuccessful()) {
emitter.onNext(response.body());
emitter.onComplete();
} else {
Gson gson = new Gson();
try {
T errorResponse = gson.fromJson(response.errorBody().string(), klazz);
emitter.onNext(errorResponse);
emitter.onComplete();
} catch (IOException e) {
emitter.onError(e);
}
}
}
}
@Override
public void onFailure(Call<T> call, Throwable t) {
if (!emitter.isDisposed()) emitter.onError(t);
}
});
}
});
}
将类似 400 的响应转换为 rx 链非常简单:
Call<Cat> request = catApi.getCat();
rxified(request, Cat.class).subscribe( (cat) -> println(cat) );
如果你想处理 onFailure 方法的响应:
@Override
public void onFailure(Call<T> call, Throwable t) {
HttpException httpException = (HttpException) t;
String errorBody = httpException.response().errorBody().string();
// use Gson to parse json to your Error handling model class
ErrorResponse errorResponse = Gson().fromJson(errorBody, ErrorResponse.class);
}
或者,如果您将 rxjava Observable 与 Kotlin 一起使用,请从错误正文中处理它:
{ error ->
val httpException :HttpException = error as HttpException
val errorBody: String = httpException.response().errorBody()!!.string()
// use Gson to parse json to your Error handling model class
val errorResponse: ErrorResponse =
Gson().fromJson(errorBody, ErrorResponse::class.java)
}
不要忘记正确处理 json 到类的转换(如果不确定,请使用 try-catch)。
switch (response.code()) {
case HttpURLConnection.HTTP_OK:
break;
case HttpURLConnection.HTTP_UNAUTHORIZED:
callback.onUnAuthentic();
break;
case HttpURLConnection.HTTP_INTERNAL_ERROR:
try {
String errorResponse = response.errorBody().string();
JSONObject object = new JSONObject(errorResponse);
String message = "Error";
if (object.has("Message"))
message = String.valueOf(object.get("Message"));
callback.onError(message);
} catch (IOException e) {
e.printStackTrace();
}
break;
case HttpURLConnection.HTTP_GATEWAY_TIMEOUT:
case HttpURLConnection.HTTP_CLIENT_TIMEOUT:
default:
callback.onNetworkError();
break;
}
if (throwable is HttpException && (throwable!!.code() == 400 || throwable!!.code()==404)){
var responseBody = throwable!!.response()?.errorBody()?.string()
val jsonObject = JSONObject(responseBody!!.trim())
var message = jsonObject.getString("message")
tvValMsg.set(message)
}
400(错误请求),请首先确保正在设置API 的输入仅是模型类,如果不是,则用模型类替换输入请求,然后检查您是否会获得成功响应。
@POST("api/users/CreateAccount")
Call<CreateAccount> createAccount(@Body CreateAccount model, @Header("Content-Type") String content_type);
if (response.isSuccessful()) {
if (response.body().getStatus().equals(1)) {
progressBar.setVisibility(View.GONE);
Toast.makeText(UploadPDFActivity.this, "Success", Toast.LENGTH_SHORT).show();
}
} else {
int statusCode = response.code();
Log.e("hello 4001", "else condition");
if (statusCode == 400) {
progressBar.setVisibility(View.GONE);
if (!response.isSuccessful()) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response.errorBody().string());
String entityId = jsonObject.getString("entity_id");
String errorMessage = jsonObject.getString("message");
String errorStatus = jsonObject.getString("status");
Log.e("hello entityId", entityId);
Log.e("hello errorMessage", errorMessage);
Log.e("hello errorStatus", errorStatus);
Toast.makeText(UploadPDFActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
} catch (JSONException | IOException e) {
e.printStackTrace();
}
}
}
else {
// Handle other error cases
}
}
}