java - com.google.gson.JsonIOException : JSON document was not fully consumed in Android Retrofit

标签 java android json retrofit2 slim

Stackoverflow 中已经有几个关于“JSON 文档未完全使用”的问题,但没有公认的答案。链接如下。

Android Retrofit 2.0 JSON document was not fully consumed

Why is JSON document not fully consumed?

在我的应用程序中,我正在接收用户的电子邮件。使用我的 API,我检查数据库中是否存在给定的电子邮件。如果存在,我将向该电子邮件发送代码。我使用 localhost 作为服务器,并使用 Slim 作为 API。我认为我的 API 没问题。我通过 postman 检查过。我在帖子中分享的 Json 响应来自 Postman。其实我正在学习Retrofit。请帮助。提前致谢。

RetrofitClient.java

package com.example.royta.retrofitdemo.APIs;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {
    private static final String BASE_URL = "http://aa561878.ngrok.io/MyApi/public/";
    private static RetrofitClient retrofitClient;
    private Retrofit retrofit;

    private static Gson gson = new GsonBuilder()
            .setLenient()
            .create();

    private RetrofitClient() {

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }

    public static synchronized RetrofitClient getInstance() {
        if(retrofitClient == null) {
            retrofitClient = new RetrofitClient();
        }
        return retrofitClient;
    }

    public Api getApi() {
        return retrofit.create(Api.class);
    }
}

Json

{
    "isSend": true,
    "code": 117482,
    "email": true
}

UserExist.java (Pojo)

package com.example.royta.retrofitdemo.ModelClass;

import com.google.gson.annotations.SerializedName;
public class UserExist {
    @SerializedName("email")
    private boolean email;
    @SerializedName("isSend")
    private boolean isSend;
    @SerializedName("code")
    private int code;

    public UserExist(boolean email, boolean isSend, int code) {
        this.email = email;
        this.isSend = isSend;
        this.code = code;
    }

    public boolean isSend() {
        return isSend;
    }

    public boolean isEmailExist() {
        return email;
    }

    public int getCode() {
        return code;
    }
}

Api.java

package com.example.royta.retrofitdemo.APIs;

import com.example.royta.retrofitdemo.ModelClass.UserExist;
import retrofit2.Call;
import retrofit2.http.GET;

public interface Api {

    @GET("finduser")
    Call<UserExist> isUserExist(
            @Query("email") String email

    );
}

电话来了👇

        Call <UserExist> call = RetrofitClient.getInstance().getApi().isUserExist(email);    
        call.enqueue(new Callback<UserExist>() {
            @Override
            public void onResponse(Call<UserExist> call, Response<UserExist> response) {
                if(response.body().isEmailExist()) {

                    String resetCode = String.valueOf(response.body().getCode());
                    Log.d("ROYs", "Reset Code: "+resetCode);
                    Intent i = new Intent(FindAccount.this, EnterSecurityCode.class);
                    i.putExtra("email", email);
                    i.putExtra("code", resetCode);
                    startActivity(i);
                }
                else {

                    Toast.makeText(FindAccount.this, "You are not registered", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<UserExist> call, Throwable t) {
                String stacktrace = Log.getStackTraceString(t);
                Log.d("ROYs", "onFailure Method: "+stacktrace);
            }
        });

Logcat

2019-01-18 19:44:23.129 29583-29583/com.example.royta.retrofitdemo D/ROYs: onFailure Method: com.google.gson.JsonIOException: JSON document was not fully consumed.
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:41)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
        at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:223)
        at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:121)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:206)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)

有时我会在同一代码中遇到以下异常

2019-01-18 21:55:39.610 1424-1424/com.example.royta.retrofitdemo D/ROYs: onFailure Method: java.net.SocketTimeoutException: timeout
        at okio.Okio$4.newTimeoutException(Okio.java:232)
        at okio.AsyncTimeout.exit(AsyncTimeout.java:285)
        at okio.AsyncTimeout$2.read(AsyncTimeout.java:241)
        at okio.RealBufferedSource.indexOf(RealBufferedSource.java:354)
        at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:226)
        at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:215)
        at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.net.SocketException: Socket closed
        at java.net.SocketInputStream.read(SocketInputStream.java:203)
        at java.net.SocketInputStream.read(SocketInputStream.java:139)
        at okio.Okio$2.read(Okio.java:140)
        at okio.AsyncTimeout$2.read(AsyncTimeout.java:237)
        at okio.RealBufferedSource.indexOf(RealBufferedSource.java:354) 
        at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:226) 
        at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:215) 
        at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189) 
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) 
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254) 
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200) 
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) 
        at java.lang.Thread.run(Thread.java:764) 

最佳答案

当我收到此错误消息“JSON 文档未完全使用”时遇到的问题只是 JSON 字符串末尾有无关的文本。

就我而言,我手动将文本添加到有效 JSON 字符串的末尾,以在周五“测试”错误处理和重试逻辑,然后周一忘记了我添加了此临时代码!

关于java - com.google.gson.JsonIOException : JSON document was not fully consumed in Android Retrofit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54256940/

相关文章:

Java - 何时使用 JSR223 脚本执行基于 java 的语言

java - 如何将枚举与 switch 语句一起使用?

Java System.out.print Windows 和 unicode 问题

android - 在微调器中选择项目 - Android

javascript - Node.js Express 和 Parse.com

android - 恢复数据放入 JSONObject 的顺序

java - 从 Java 代码创建 AVD 设备。库或其他解决方案

android - 如何使用共享首选项保存切换按钮状态

android - Android Jelly Bean 中的应用加密

Java REGEX .replaceall() 不适用于特定 JSON 对象(转换为字符串)