背景
在使用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>
這和上面的那兩個接口是不一樣的。
解決方案
- 請服務端人員吃頓飯,讓他們規範接口,當數據爲空時,返回null或者[]
- 自己動手豐衣足食
自定義一個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
參考:
retrofit issues