最近要做一个需求,比较特别的是这次业务数据后端是放在http状态码403返回的(一万只草泥马),以往都是直接解析200里面的数据,因为retrofit框架最终吐出来的数据都是给解析好了的最终需要类型的数据,而不是response,所以只能在网络层,通过拦截器进行处理,这样:
val headerInterceptor = Interceptor { chain ->
val request: Request = chain.request()
val builder: Request.Builder = request.newBuilder()
val response = chain.proceed(builder.build())
//再次吐槽一下,403特么是干这个的嘛。。
if (response.code() == 403) {
val resString = response.body()?.string()
//do something
}
response
}
满心欢喜的写完去测试一下,发现,直接给我报错,看了一下错误信息是:java.lang.IllegalStateException: closed。。。一脸懵逼。
查了半天才发现, response.body()?.string()只能调用一次,调用后流就直接被关掉了,所以报错,具体代码看这篇文章:
为何 response.body().string() 只能调用一次?
由于这篇文章中的解决方案(保留一份)并不适合我,我用的是retrofit+rxjava,因此只能想别的方法:
万能的stackoverflow大佬们提供的解决方法
因此这样干。。。。
val headerInterceptor = Interceptor { chain ->
val request: Request = chain.request()
val builder: Request.Builder = request.newBuilder()
val response = chain.proceed(builder.build())
if (response.code() == 403) {
val source = response.body()?.source()
source?.request(Long.MAX_VALUE)
val buffer = source?.buffer()
val resString = buffer?.clone()?.readString(Charset.forName("UTF-8"))
//do something
}
response
}
核心就是把buffer clone一份,用clone的buffer去操作返回的json数据~
特此记录~!
网友评论