Android 改装2.0-如何获得400错误请求的响应正文?

Android 改装2.0-如何获得400错误请求的响应正文?,android,retrofit,Android,Retrofit,因此,当我对我的服务器进行POST API调用时,JSON响应会出现400个错误请求 {  "userMessage": "Blah", "internalMessage": "Bad Request blah blah", "errorCode": 1 } 我打电话给你 Call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<Re

因此,当我对我的服务器进行POST API调用时,JSON响应会出现400个错误请求

{
    "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
    }
}
Call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
//AA
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
//BB
}
}
但是问题是,一旦我得到响应,onFailure()将被调用,以便调用//BB。在这里,我无法访问JSON响应。 当我记录api请求和响应时,它根本不显示JSON响应。Throwable t是IOException。然而,奇怪的是,当我对Postman进行相同的调用时,它确实返回了预期的JSON响应,并返回了400个错误代码

所以我的问题是,当我收到400个错误的请求错误时,如何获得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
编译'com.google.code.gson:gson:2.7'


如果您想创建
Pojo
类,请转到并粘贴您的示例
Json
响应。选择源类型Json和注释Gson,我遇到了类似的问题,但现有代码仍然坚持使用RxJava 2链。 以下是我的解决方案:

   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);
                    }
                });
        }
    });
}
publicstaticobserveable rxified(最终调用请求,最终类klazz){
返回Observable.create(newobservableOnSubscribe(){
AtomicBoolean=new AtomicBoolean(false);
@凌驾
public void subscribe(最终ObservieMitter发射器)引发异常{
emitter.setDispossible(新的Dispossible(){
@凌驾
公共空间处置(){
request.cancel();
justDisposed.set(true);
}
@凌驾
公共布尔值isDisposed(){
返回justDisposed.get();
}
});
如果(!emitter.isDisposed())
request.enqueue(新回调(){
@凌驾
公共void onResponse(呼叫,改装2.响应){
如果(!emitter.isDisposed()){
if(response.issusccessful()){
emitter.onNext(response.body());
emitter.onComplete();
}否则{
Gson Gson=新的Gson();
试一试{
T errorResponse=gson.fromJson(response.errorBody().string(),klazz);
发射器.onNext(错误响应);
emitter.onComplete();
}捕获(IOE异常){
发射体。onError(e);
}
}
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
如果(!emitter.isDisposed())emitter.onError(t);
}
});
}
});
}
将400个类似的响应转换为rx链非常简单:

Call<Cat> request = catApi.getCat();
rxified(request, Cat.class).subscribe( (cat) -> println(cat) );
callrequest=catApi.getCat();
rxified(请求,Cat.class).subscribe((Cat)->println(Cat));
您可以尝试以下代码以获得400响应。您可以从errorBody()方法获得错误响应

Call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
//在此处获取成功和错误响应
if(response.code()==400){
如果(!response.issusccessful()){
JSONObject JSONObject=null;
试一试{
jsonObject=newJSONObject(response.errorBody().string());
stringusermessage=jsonObject.getString(“userMessage”);
String internalMessage=jsonObject.getString(“internalMessage”);
String errorCode=jsonObject.getString(“errorCode”);
}捕获(JSONException e){
e、 printStackTrace();
}
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
//在这里获取失败响应
}
}
}

编辑:将方法名称从
toString
固定到
string
这是处理响应消息的方式 我正在处理错误500,您可以添加任意数量

                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;
                }

第一步:

为错误响应创建POJO类。在我的例子中,
apierro.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
     }
}
Call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应)
{
if(response.issusccessful()){
//请在这里输入您的代码
}else if(response.code()==400){
转换器=
ApiClient.Reformation.responseBodyConverter(apierr.class,新注释[0]);
误差;
试一试{
error=converter.convert(response.errorBody());
Log.e(“错误消息”,error.getErrorMessage());
Toast.makeText(上下文,error.getErrorMessage(),Toast.LENGTH_LONG.show();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
@凌驾
失败时公共无效(调用调用,Throwa
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
     }
}
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();
        }
    }
}
@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);
}
{ 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)
}
val errorResponse = Gson().fromJson(response.errorBody()!!.charStream(), ErrorResponse::class.java)
ErrorResponse errorResponse = new Gson().fromJson(response.errorBody.charStream(),ErrorResponse.class)
 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)
                            } 
@POST("api/users/CreateAccount")
Call<CreateAccount> createAccount(@Body CreateAccount model, @Header("Content-Type") String content_type);