android retrofit End of input at line 1 column 1 path

本文介绍在使用Retrofit进行网络请求时,如何处理服务端返回的空响应问题,包括自定义转换器工厂的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

在使用retrofit作为项目的网络请求库时,接口定义如下:

@GET(ACT_GET_NEW_STAFF)
Call<TaskEn> reqGetNewStaff();

@GET(ACT_GET_NEW_STAFF_MORE)
Call<List<TaskEn>> reqGetNewStaffMore(@Query("index")int index, @Query("size")int size);

上面两个接口从服务端获取了数据,通过GsonConverterFactory将服务端相应内容解析成对应的实体类。在接口正常响应时(有数据返回),并没有什么异常发生,但当接口请求的数据为空,我们的服务端人员并不是返回理论意义上的空,null或者[](数据集合空),而是返回没有响应体body,只有响应头header,content-length为0的Response

这时候GsonConverterFactory就解析异常了,并抛出如下异常:

java.io.EOFException:End of input at line 1 column 1 path $

一般来说,如果接口本身就是不需要处理body的,那么我们通常定义接口为

Call<Void>
这和上面的那两个接口是不一样的。


解决方案

  1. 请服务端人员吃顿饭,让他们规范接口,当数据为空时,返回null或者[]
  2. 自己动手丰衣足食

自定义一个ConverterFactory

public class NullOnEmptyConverterFactory extends Converter.Factory {

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        final Converter<ResponseBody, ?> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);
        return new Converter<ResponseBody,Object>() {
            @Override
            public Object convert(ResponseBody body) throws IOException {
                if (body.contentLength() == 0) return null;
                return delegate.convert(body);
            }
        };
    }
}
然后设置到retrofit

Retrofit retrofit = new Retrofit.Builder()
    ....
    .addConverterFactory(new NullOnEmptyConverterFactory())
    .addConverterFactory(GsonConverterFactory.create())
    .build();
需要注意的是,NullOnEmptyConverterFactory必需在GsonConverterFactory之前addConverterFactory


<think>好的,用户遇到了JSON解析的问题,具体是出现了“Use JsonReader.setLenient(true) to accept malformed JSON”的错误。首先,我需要回忆一下这个错误的常见原因。通常,当JSON格式不符合严格标准时,Gson解析器会抛出这个异常。用户可能需要允许解析非标准格式的JSON,比如缺少引号、注释或者不正确的分隔符。 接下来,用户想知道如何应用JsonReader.setLenient(true)来解决这个问题。我应该先检查用户提到的引用内容,特别是引用[3]和[4],里面提到了GsonConverterFactory的配置和Retrofit的设置。可能的解决方法包括在创建Gson实例时启用宽松模式,或者在Retrofit的转换器工厂中应用这个设置。 然后,我需要分步骤说明如何操作。首先,如何自定义Gson实例,设置setLenient(true),然后在Retrofit构建时使用这个自定义的Gson。同时,用户可能需要直接使用JsonReader的情况,这时候需要手动设置reader的宽松模式。 还要注意用户提到的错误发生在路径$,这通常表示根元素的问题,可能是空的JSON或者格式错误。可能需要检查API返回的数据是否正确,是否有额外的字符或结构问题。此外,引用[4]中提到的检查Retrofit配置,比如路径是否正确、是否缺少斜杠,这些也是需要提醒用户的。 最后,需要总结可能的原因和解决方案,确保用户能够一步步排查问题。同时,生成的相关问题要围绕JSON解析错误、Retrofit配置、Gson的其他异常处理等,帮助用户扩展了解。</think>### 如何通过 `JsonReader.setLenient(true)` 处理畸形JSON错误? #### 问题背景 当使用Gson解析JSON数据时,如果数据格式不符合严格标准(如缺少引号、包含注释、未闭合的括号等),会触发以下错误: ``` Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $ ``` 此错误表明解析器检测到格式异常,需通过**宽松模式(Lenient)**允许解析非标准JSON[^1][^3]。 --- #### 解决方案分步说明 ##### 方法1:修改Gson解析配置 **适用场景**:通过Gson直接解析数据或结合Retrofit使用。 1. **自定义Gson实例**:创建Gson对象时启用`setLenient`模式。 ```java Gson gson = new GsonBuilder() .setLenient() // 启用宽松模式 .create(); ``` 2. **在Retrofit中应用**: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create(gson)) // 使用自定义Gson .build(); ``` 此配置允许解析非标准JSON响应[^4]。 ##### 方法2:直接操作JsonReader **适用场景**:手动解析JSON字符串时。 ```java JsonReader reader = new JsonReader(new StringReader(jsonString)); reader.setLenient(true); // 设置宽松模式 MyData data = gson.fromJson(reader, MyData.class); ``` ##### 方法3:检查API响应数据 若错误仍存在,需验证返回的JSON是否合法: 1. 使用在线工具(如[JSONLint](https://jsonlint.com/))验证JSON格式。 2. 确保响应体非空且以`{`或`[`开头,而非纯字符串(如`"OK"`)。 --- #### 可能原因总结 | 原因 | 解决步骤 | |---------------------|----------------------------------| | JSON缺少引号/括号 | 启用`setLenient(true)`或修正数据 | | API返回非JSON内容 | 检查响应是否为合法JSON | | Retrofit路径配置错误| 确认接口路径是否包含多余的`/`| ---
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值