最近要做一個(gè)需求,比較特別的是這次業(yè)務(wù)數(shù)據(jù)后端是放在http狀態(tài)碼403返回的(一萬(wàn)只草泥馬),以往都是直接解析200里面的數(shù)據(jù),因?yàn)閞etrofit框架最終吐出來(lái)的數(shù)據(jù)都是給解析好了的最終需要類(lèi)型的數(shù)據(jù),而不是response,所以只能在網(wǎng)絡(luò)層,通過(guò)攔截器進(jìn)行處理,這樣:
val headerInterceptor = Interceptor { chain ->
val request: Request = chain.request()
val builder: Request.Builder = request.newBuilder()
val response = chain.proceed(builder.build())
//再次吐槽一下,403特么是干這個(gè)的嘛。。
if (response.code() == 403) {
val resString = response.body()?.string()
//do something
}
response
}
滿心歡喜的寫(xiě)完去測(cè)試一下,發(fā)現(xiàn),直接給我報(bào)錯(cuò),看了一下錯(cuò)誤信息是:java.lang.IllegalStateException: closed。。。一臉懵逼。
查了半天才發(fā)現(xiàn), response.body()?.string()只能調(diào)用一次,調(diào)用后流就直接被關(guān)掉了,所以報(bào)錯(cuò),具體代碼看這篇文章:
為何 response.body().string() 只能調(diào)用一次?
由于這篇文章中的解決方案(保留一份)并不適合我,我用的是retrofit+rxjava,因此只能想別的方法:
萬(wàn)能的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數(shù)據(jù)~
特此記錄~!