com.google.gson.JsonIOException:JSON文档未在Android Retrofit中完全使用

时间:2019-01-18 15:26:11

标签: 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,检查数据库中是否存在给定的电子邮件。如果存在,我正在向该电子邮件发送代码。我使用本地主机作为服务器,并且使用了Slim for API。我认为我的API可以。我通过邮递员检查了它。我在帖子中分享的Json回复来自Postman。实际上,我正在学习改造。请帮助。预先感谢。

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)

有时我会在同一代码中收到以下Exception

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) 

2 个答案:

答案 0 :(得分:1)

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

在我的情况下,我手动将文本添加到有效JSON字符串的末尾,以在星期五和星期一之前“测试”错误处理并重试逻辑,而忘记了我添加了此临时代码!

答案 1 :(得分:0)

您应该按照与json中相同的顺序将字段放入模型类中

@SerializedName("isSend")
private boolean isSend;
@SerializedName("code")
private int code;
@SerializedName("email")
private boolean email;