【问题标题】:How to obtain the body of a retrofit request when it fails?失败时如何获取改造请求的正文?
【发布时间】:2017-11-06 14:46:57
【问题描述】:

我正在使用 RxJava 进行改造。我想知道当请求失败或成功时如何检索请求发送的 BODY/RAW。

这是我的控制器调用 API:

ChatMessage body = new ChatMessage();
    ...
    //configuration of body variable is omitted.
    ...

chatController.sendMessage(body).subscribe(this::onSendMessageSuccess, this::onSendMessageError);

这些是接收答案的方法:

private void onSendMessageSuccess(ChatRestResponse response) {
   // How can I get the "ChatMessage body" sent in at first by the re
}

private void onSendMessageError(Throwable throwable) {
     // How can I get the "ChatMessage body" sent in at first by the request       
}

我想知道如何获取我用来发出请求的 ChatMessage 类。

仅供参考

这是我的界面:

@Headers({
     "Accept: application/json",
     "Content-Type: application/json"
})
@POST(URL)
Observable<ChatRestResponse> sendMessage(
     @Header("Authorization") String token,
     @Body ChatMessage body);

这是我调用 api 的控制器:

public Observable<ChatRestResponse> sendMessage(ChatMessage body) {
     String accessToken = mPref.getAccesToken();

     return mChatApi.sendMessage(accessToken , body)
         .subscribeOn(Schedulers.newThread())
         .observeOn(AndroidSchedulers.mainThread());
}

【问题讨论】:

    标签: android retrofit2 rx-android rx-java2


    【解决方案1】:

    Brother On Failure,没有响应的实体存在。只会有一些与它所面临的错误相关的代码。比如404等 但是,如果您谈论的是您自己的服务器响应失败。就像您通过 Retrofit 从您的应用程序登录到您的帐户一样。如果您输入错误的凭据,互联网和与服务器的连接一切正常,即使这样,响应也会运行函数 onResponce() 。但是在这里您可以检查服务器将发送的与类型或错误相关的服务器内部错误。

    call.enqueue(new Callback<LoginResponse>() {
                        @Override
                        public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
                            if (response.code == HttpURLConnection.HTTP_OK) {
                                //All is well
                                // you can get body here as 
                                String token = responce.body().getToken();
                                //etc
                            } else {
                               //Something went wrong like password etc
                               //You can check the body here also in case of failure
                               //Which is due to some internal server error
                               //because of wrong credentials
                               //But this response is in failure and also have a body 
                               //I guess this is what u want
                               String failuerToken = responce.getBody().getAccessToken();
                                new AlertDialog.Builder(LoginActivity.this)
                                        .setMessage("Invalid Credentials")
                                        .setCancelable(false)
                                        .setPositiveButton("Try Again", null)
                                        .show();
                            }
                        }
    
                        @Override
                        public void onFailure(Call call, Throwable t) {
                            showProgress(false);
    
                            new AlertDialog.Builder(LoginActivity.this)
                                    .setMessage("Unable to reach server")
                                    .setCancelable(false)
                                    .setPositiveButton("Try Again", null)
                                    .show();
                            call.cancel();
                        }
                    });
    

    请注意

    LoginResponse 
    

    是我自己的班级

    public class LoginResponse {
        @SerializedName("access_token")
        @Expose
        public String accessToken;
        @SerializedName("token_type")
        @Expose
        public String tokenType;
        @SerializedName("expires_in")
        @Expose
        public Integer expiresIn;
    }
    

    更新

    Call<LoginResponse> call = apiInterface.Login(requestData);
    

    请参阅我正在使用 requestData 发送数据。解决您的问题的唯一方法是创建一个单独的包名称 urils,创建一个类 RequestData 并在其中放入一些静态变量。

    public class RequestData {
        public static String username;
        public static String password;
        public static String email;
        public static Int age;
        //etc
    }
    

    像这样设置变量值

    RequestData.username = "abcd";
    RequestData.password = "abcd";
    RequestData.email = "abcd@email.com";
    RequestData.age = 20";
    

    然后通过api call发送数据。

    失败后使用这个类来访问之前的数据并分别显示在 UI 上。

    【讨论】:

    • @Deneb Chorny 这是完美的答案。失败时没有响应体存在,所以你必须使用回调的 onFailure 方法。
    • 答案很好,我已经知道了,感谢您的回答。但是我想知道有没有办法制作拦截器?我是说。我希望如果有错误或成功能够获取我作为原始/正文发送的对象。为什么?因为我想在创建请求的确切对象中更新 UI。希望有解决办法
    • @DenebChorny 请查看上面答案中的更新
    • 这不是 RxJava
    • 如果我使用静态变量,想象一下发出多个请求。因为这个原因我问了这个问题,否则甚至没有必要使用静态变量。
    猜你喜欢
    • 1970-01-01
    • 2015-11-25
    • 2020-11-07
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 2018-02-20
    • 2019-05-20
    • 2015-08-18
    相关资源
    最近更新 更多