使用相同的url和不同的accept标头进行请求将返回okhttp缓存的先前响应。

这意味着第一个请求是针对application / json数据,第二个请求是application / xml。因此,客户端从缓存返回json数据,而不是在上游执行xml。

例如,带有标头application / json的GET请求:http://example.com返回Cache-Control标头和json有效负载。
响应被缓存在内部http缓存中。
第二个请求是在标题为application / xml的缓存控制窗口中向http://example.com发出的。在这种情况下,Okhttp从缓存返回相同的json有效负载,而不是xml有效负载。

Builder builder = new Builder().url("https://httpbin.org/headers").header("accept", header);


有人遇到过这个问题吗?

最佳答案

描述缓存应如何工作的相关RFC在这里:https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6


  如果缓存条目的选择请求标头字段与新请求的选择请求标头字段不匹配,则缓存必须禁止使用缓存条目满足请求,除非它先在条件条件下将新请求中继到原始服务器请求,服务器以304(未修改)响应,包括指示要使用的实体的实体标签或Content-Location。


OkHttp的Cache的源代码在这里:https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Cache.java

缓存键就是资源的URL。但是缓存条目也会与“变化的”请求标头进行比较:

Response response = entry.response(snapshot);

if (!entry.matches(request, response)) {
  Util.closeQuietly(response.body());
  return null;
}


...

public boolean matches(Request request, Response response) {
  return url.equals(request.url().toString())
      && requestMethod.equals(request.method())
      && HttpHeaders.varyMatches(response, varyHeaders, request);
}


当然,您可能已经发现了一个错误。我建议引入OkHttp源JAR,在Cache.get()方法中使用断点进行调试,并逐步检查是否/何时出错。如果是这样,请向维护者提出或提交补丁。

关于java - OkHttp客户端不尊重Accept header ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41124688/

10-12 13:34