okhttp拦截器报错:java.lang.IllegalStateException: closed

最近要做一个需求,比较特别的是这次业务数据后端是放在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大佬们提供的解决方法

官方github大佬们也提供解决方案,但是思路都是一样的

因此这样干。。。。

   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数据~

特此记录~!

你可能感兴趣的:(okhttp拦截器报错:java.lang.IllegalStateException: closed)