即使数据不是NULL,onResponse中的Retrofit2 NULL响应

时间:2018-07-22 14:27:44

标签: android json nullpointerexception retrofit2

所以,我的问题很简单。

这是我通过API调用得到的响应。

D/OkHttp: {"status":"error","status_code":"500","error_msg":"There was an error trying to send the password reset email."}
<-- END HTTP (220-byte body)

这是我处理电话的代码

 Call<PasswordReset> forgotPasswordCall = apiInterface.Reset(email);
    forgotPasswordCall.enqueue(new Callback<PasswordReset>() {
        @Override
        public void onResponse(Call<PasswordReset> call, Response<PasswordReset> response) {
            PasswordReset passwordReset = response.body();
            try {
                if (passwordReset.getStatusCode() != null && passwordReset.getStatusCode().equals("200")) {   //line 133
                    Log.d("Success", "Password Reset Email Sent");
                    new CustomToast().showToast(getContext(), view, "Password Email sent");
                    new LoginActivity().replaceFragment("left");
                } else {
                    String test = passwordReset.getStatusCode();
                    Log.d("Failure", test);
                    hideDialog();
                }
            }
            catch (Exception e){
                e.printStackTrace();
                hideDialog();
            }
        }

        @Override
        public void onFailure(Call<PasswordReset> call, Throwable t) {
            Log.d("Failure", "Password Reset Email Not Sent");
            new CustomToast().showToast(getContext(), view, "Email Not Sent");
            new LoginActivity().replaceFragment("left");
            hideDialog();
        }
    });

这是我捕捉到的异常

W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String in.siddhant.anetpays_customer.POJO.PasswordReset.getStatusCode()' on a null object reference
    at in.siddhant.anetpays_customer.Login.Fragments.ForgotPassword$1.onResponse(ForgotPassword.java:133)

如果我得到一些数据,我的答复怎么能为空?

PasswordReset.class

    public class PasswordReset {


    @SerializedName("data")
    private String data;
    @SerializedName("status_code")
    private String statusCode;
    @SerializedName("status")
    private String status;

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(String statusCode) {
        this.statusCode = statusCode;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

改造客户端

public static Retrofit getClient() {

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();


        retrofit = new Retrofit.Builder()
                .baseUrl("http://xsdf/")
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();



        return retrofit;

API_Interface

@FormUrlEncoded
    @POST("/ddd/pwdresetrequest")
    Call<PasswordReset>Reset(@Field("email")String email);

P.S-API本身有问题,总是返回"status":"error",但这不应该影响应用程序,对吗?我也很高兴分享更多代码。 预先感谢。

解决方案 我将按照接受的答案按照建议的方式发布解决方案,希望它可以帮助寻求帮助的人。

forgotPasswordCall.enqueue(new Callback<PasswordReset>() {
            @Override
            public void onResponse(Call<PasswordReset> call, Response<PasswordReset> response) {
                     if (!response.isSuccessful()){
                        Gson gson = new Gson();
                        PasswordReset passwordReset1 = gson.fromJson(response.errorBody().charStream(), PasswordReset.class);
                        if (passwordReset1.getStatusCode().equals("500")){
                            new CustomToast().showToast(getContext(), view, "Password Email not sent");
                            hideDialog();
                        }
                        else {
                            Thread.dumpStack();
                            hideDialog();
                        }

                    }
                     else if (response.isSuccessful()) {
                         Log.d("Success", "Password Reset Email Sent");
                         new CustomToast().showToast(getContext(), view, "Password Email sent");
                         new LoginActivity().replaceFragment("left");
                     }

从理论上讲,当我们获得一些响应时,将调用retrofit2的onResponse方法,而当不满足建立和接收响应的过程时,将调用onFailure。我忽略了这个简单的事实。 因此,如果有人确实看了看又看书,我建议您也检查一下response.body()是否成功。 祝您编码愉快!

1 个答案:

答案 0 :(得分:1)

Response的改造版Javadoc中可以看出,body()成功响应返回反序列化响应。不幸的是,鉴于您似乎收到了500分,因此您似乎未获得成功的答复。

errorBody()是您要使用的。但是,这将返回原始响应,因此您必须自己对其进行反序列化。

有很多方法可以做到这一点。一个人可能正在使用gson对身体进行反序列化:

new Gson().fromJson(response.errorBody().body().string(), YourModel.class);

PS:仅仅因为您最终获得onResponse并不意味着您获得了成功的答复。但是,从您的代码看来,您似乎已经知道这一点,并且正在检查http状态200