1. 程式人生 > >android retrofit End of input at line 1 column 1 path

android retrofit End of input at line 1 column 1 path

背景

在使用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