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

我一直在尝试实现拦截器(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; } } 

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

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

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

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

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

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

澄清

Square在他们的wiki上有这个有用的图表,显示每种types的拦截器所在的位置

拦截图

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

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