[java] Retrofit 2.0 직렬화 해제 오류 응답을 얻는 방법

내가 사용하고 개조 2.0.0-β1을 .

테스트에서 대체 시나리오가 있으며 HTTP 400 오류가 예상됩니다.

갖고 retrofit.Response<MyError> response
싶지만response.body() == null

MyError는 직렬화 해제되지 않았습니다. 여기서 만 볼 수 있습니다.

response.errorBody().string()

하지만 객체로 MyError를주지 않습니다.



답변

나는 현재 매우 쉬운 구현을 사용하고 있으며 변환기 또는 특수 클래스를 사용할 필요가 없습니다. 내가 사용하는 코드는 다음과 같습니다.

public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
    DialogHelper.dismiss();

    if (response.isSuccessful()) {
        // Do your success stuff...
    } else {
        try {
            JSONObject jObjError = new JSONObject(response.errorBody().string());
            Toast.makeText(getContext(), jObjError.getJSONObject("error").getString("message"), Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }
}


답변

ErrorResponse 는 사용자 정의 응답 객체입니다

코 틀린

val gson = Gson()
val type = object : TypeToken<ErrorResponse>() {}.type
var errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type)

자바

Gson gson = new Gson();
Type type = new TypeToken<ErrorResponse>() {}.getType();
ErrorResponse errorResponse = gson.fromJson(response.errorBody.charStream(),type);


답변

나는 그것을 해결했다 :

 if(!response.isSuccessful()){
       Gson gson = new Gson();
       MyErrorMessage message=gson.fromJson(response.errorBody().charStream(),MyErrorMessage.class);
       if(message.getCode()==ErrorCode.DUPLICATE_EMAIL_ID_CODE){
                  //DO Error Code specific handling                        
        }else{
                 //DO GENERAL Error Code Specific handling                               
        }
    }

MyErrorMessage 클래스 :

  public class MyErrorMessage {
     private int code;
     private String message;

     public int getCode() {
        return code;
     }

     public void setCode(int code) {
        this.code = code;
     }

     public String getMessage() {
         return message;
     }

     public void setMessage(String message) {
        this.message = message;
     }
   }


답변

Retrofit 2.0 베타 2에서 이것은 오류 응답을 얻는 방법입니다.

  1. 동기식

    try {
       Call<RegistrationResponse> call = backendServiceApi.register(data.in.account, data.in.password,
               data.in.email);
       Response<RegistrationResponse> response = call.execute();
       if (response != null && !response.isSuccess() && response.errorBody() != null) {
           Converter<ResponseBody, BasicResponse> errorConverter =
                   MyApplication.getRestClient().getRetrofitInstance().responseConverter(BasicResponse.class, new Annotation[0]);
           BasicResponse error = errorConverter.convert(response.errorBody());
           //DO ERROR HANDLING HERE
           return;
       }
       RegistrationResponse registrationResponse = response.body();
       //DO SUCCESS HANDLING HERE
    } catch (IOException e) {
       //DO NETWORK ERROR HANDLING HERE
    }
  2. 비동기

    Call<BasicResponse> call = service.loadRepo();
    call.enqueue(new Callback<BasicResponse>() {
        @Override
        public void onResponse(Response<BasicResponse> response, Retrofit retrofit) {
            if (response != null && !response.isSuccess() && response.errorBody() != null) {
                Converter<ResponseBody, BasicResponse> errorConverter =
                    retrofit.responseConverter(BasicResponse.class, new Annotation[0]);
                BasicResponse error = errorConverter.convert(response.errorBody());
                //DO ERROR HANDLING HERE
                return;
            }
            RegistrationResponse registrationResponse = response.body();
            //DO SUCCESS HANDLING HERE
        }
    
        @Override
        public void onFailure(Throwable t) {
            //DO NETWORK ERROR HANDLING HERE
        }
    });

Retrofit 2 베타 3 업데이트 :

  1. 동기식-변경되지 않음
  2. 비동기-개장 매개 변수가 onResponse에서 제거되었습니다.

    Call<BasicResponse> call = service.loadRepo();
    call.enqueue(new Callback<BasicResponse>() {
        @Override
        public void onResponse(Response<BasicResponse> response) {
            if (response != null && !response.isSuccess() && response.errorBody() != null) {
                Converter<ResponseBody, BasicResponse> errorConverter =
                    MyApplication.getRestClient().getRetrofitInstance().responseConverter(BasicResponse.class, new Annotation[0]);
                BasicResponse error = errorConverter.convert(response.errorBody());
                //DO ERROR HANDLING HERE
                return;
            }
            RegistrationResponse registrationResponse = response.body();
            //DO SUCCESS HANDLING HERE
        }
    
        @Override
        public void onFailure(Throwable t) {
            //DO NETWORK ERROR HANDLING HERE
        }
    });

답변

에서는 https://stackoverflow.com/a/21103420/2914140https://futurestud.io/tutorials/retrofit-2-simple-error-handling 이 변형 개조 2.1.0 도시되어있다.

call.enqueue(new Callback<MyResponse>() {
    @Override
    public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
        if (response.isSuccessful()) {
            ...
        } else {
            Converter<ResponseBody, MyError> converter
                    = MyApplication.getRetrofit().responseBodyConverter(
                    MyError.class, new Annotation[0]);
            MyError errorResponse = null;
            try {
                errorResponse = converter.convert(response.errorBody());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


답변

 @Override
 public void onResponse(Call<Void> call, retrofit2.Response<Void> response) {
            if (response.isSuccessful()) {

            //Do something if response is ok
            } else {

                JsonParser parser = new JsonParser();
                JsonElement mJson = null;
                try {
                    mJson = parser.parse(response.errorBody().string());
                    Gson gson = new Gson();
                    MyError errorResponse = gson.fromJson(mJson, MyError.class);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

            }


답변

오류 응답 및 사용자 Gson의 모델을 작성하여 응답을 변환하십시오. 이것은 잘 작동합니다.

APIError.java

public class APIError {
    private String message;

    public String getMessage() {
        return message;
    }
}

MainActivity.java (요청에 대한 응답 내)

if (response.isSuccessful()) {
    // Do your success stuff...

} else {
    APIError message = new Gson().fromJson(response.errorBody().charStream(), APIError.class);
    Toast.makeText(MainActivity.this, "" + message.getMessage(), Toast.LENGTH_SHORT).show();
}