【问题标题】:Retrofit onResponse's value impossible to get改造 onResponse 的值不可能得到
【发布时间】:2017-12-18 18:11:35
【问题描述】:

我正在调用本地服务器的 API 来验证是否发生错误 400。此错误按预期发生。在这一刻,我想获得价值。它是一个 JSON 对象。 来自服务器的消息即将到来,但某个时刻的值消失了。我知道这是因为我正在调试应用程序。在来自 Retrofit 的 response.errorBody().string() 消息的第一个响应中,字符串值就在那里。但在响应之后,值变为空。我放了一张图片来说明发生了什么。

我的代码是:

public class ServerResponse implements Parcelable {

@SerializedName("message")
private String message;

public ServerResponse(){}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeString(message);
}

public ServerResponse(String message){
    this.message = message;
}

private ServerResponse(Parcel parcel){
    message = parcel.readString();
}

public static final Parcelable.Creator<ServerResponse> CREATOR =
        new Parcelable.Creator<ServerResponse>() {
            public ServerResponse createFromParcel(Parcel in) {
                return new ServerResponse(in);
            }

                public ServerResponse[] newArray(int size) {
                    return new ServerResponse[size];
                }
            };

    public String getMessage(){
        return message;
    }
}

这是另一段代码:

        super.data.restApi(WorkOrderAPI.class)
            .answerWorkOrder(
                    t,
                    workOrderId,
                    request.getQuestionFormId(),
                    isOffline ? 1 : 0,
                    request)
            .enqueue(new Callback<ServerResponse>() {
                @Override
                public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
                    if (response.isSuccessful()) {
                        onResult.onSuccessful(null);
                    } else {
                        try {
                            if(response.code() == 400) {
                                Gson gson = new GsonBuilder()
                                        .registerTypeAdapter(Date.class, new DateTypeDeserializer())
                                        .create();
                                ServerResponse serverResponse = gson.fromJson(response.errorBody().charStream(), ServerResponse.class);
                                onResult.onUnsuccessful(new DefaultError(response.code(), serverResponse.getMessage()));
                            }

为什么在第一行代码之后值就消失了?

【问题讨论】:

    标签: android retrofit2


    【解决方案1】:

    来自documentation

    响应正文只能使用一次。

    您正在消费它两次。第一次返回值,第二次返回null。

    【讨论】:

    • 此行为自第一次 response.errorBody() 起发生。我删除了那部分代码,但问题仍然存在。
    • @learner 你可以尝试使用string() 方法而不是charStream() 来阅读正文吗?
    • 我发现了错误。就像你说的,我吃了两次。我在调试时使用它。在图片上看到它。
    【解决方案2】:

    基本上发生的事情是:

    在第一个if(response.code() == 400) 中,你得到了errorBody,你让Gson 解析它。所以现在 JSON 已经被消费了,它消失了。

    然后当到达第二个if(response.code() == 400) 时,不再有 JSON。

    问题是:为什么要解析两次errorBody?

    只要做:

    @Override
    public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {                 
        if (response.isSuccessful()) {
            onResult.onSuccessful(null);
        } else {
            try {
                if(response.code() == 400) {
                    Gson gson = new GsonBuilder()
                            .registerTypeAdapter(Date.class, new DateTypeDeserializer())
                            .create();
                    ServerResponse serverResponse = gson.fromJson(response.errorBody().charStream(), ServerResponse.class);
                    onResult.onUnsuccessful(new DefaultError(response.code(), serverResponse.getMessage()));
                }
            }
            // ... catch...
        }   
    }
    

    【讨论】:

    • 自第一个响应以来,正文为空。这让我发疯。我删除了该代码,但问题仍然存在。
    • 我发现了错误。就像你说的,我吃了两次。我在调试时使用它。在图片上看到它。
    【解决方案3】:

    发现错误。就像受访者说我消费了两次。我在调试时使用它。在图片上看到它。

    【讨论】:

      猜你喜欢
      • 2016-08-15
      • 1970-01-01
      • 2021-03-27
      • 2020-07-04
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多