Android Retrofit 2,addInterceptor和addNetworkInterceptor之间的差异用于编辑响应

Jos*_*hon 23 android interceptor retrofit2 okhttp3

我一直在尝试实现拦截器(OkHttp 3.2和Retrofit 2),以便在作为响应返回之前编辑JSON响应.我们请求数据的服务器返回成功或错误的不同数据依赖性,这使得难以映射对象.

我试图通过将拦截器添加到Retrofit作为NetworkInterceptor来实现,但返回的字符串没有格式.

@Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        Response response = chain.proceed(request);
        try {

            final String responseString = new String(response.body().bytes() ); 

            LOGD("OkHttp-NET-Interceptor", "Response: " + responseString);

            String  newResponseString = editResponse( responseString );

            LOGD("OkHttp-NET-Interceptor", "Response edited: " + newResponseString);
            return  response.newBuilder()
                    .body(ResponseBody.create(response.body().contentType(), newResponseString))
                    .build();

        }catch (Exception ex){
            return response;
        }
    }
Run Code Online (Sandbox Code Playgroud)

responseString有一个没有任何可理解格式的字符串.

在更改为普通拦截器之后,字符串具有能够转换为JSONObject的格式.

可以告诉我某些回复之间的差异吗?

为什么这行新的String(response.body().bytes()); 返回不同的内容?

roa*_*ter 49

不同之处在于名称.NetworkInterceptor挂钩在网络级别,是一个理想的地方放置重试逻辑和任何不依赖于响应的实际内容.

如果你做的事情取决于响应的内容(就像你的情况一样),使用a ApplicationInterceptor更有用,因为它会在你可能拥有的任何其他移动部件(如JSON解串器)处理后给出响应.否则你必须自己实现JSON反序列化NetworkInterceptor,考虑到它是由Retrofit为你完成的,没有多大意义.

澄清

Square在他们的维基上有这个有用的图表,显示每种类型的拦截器所在的位置

拦截图

因此,你收到一个可读字符串的原因ApplicationInterceptor是因为Square试图解除两个拦截器类型的目的.他们认为您不应该在其中做出任何依赖于应用程序的决策NetworkInterceptor,因此它们不会为您提供访问响应字符串的简便方法.有可能获得支持,但正如我所说,他们不希望您做出取决于响应内容的决策 - 相反,他们希望您根据决策或网络状态或标题等做出决策.

ApplicationInterceptor是他们希望您根据响应内容做出决策的地方,因此它们提供了更简单的方法来访问响应的内容,以便您可以做出明智的决策来重试,或者当他们在wiki中详细说明时,重写响应(我认为这是你要做的事情.