java - OkHttp 客户端不尊重 Accept header

标签 java json okhttp

使用相同的 url 和不同的接受 header 发出请求会从 okhttp 缓存返回先前的响应。

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

例如 GET 请求:http://example.com使用 header application/json 返回 Cache-Control header 和 json 负载。 响应被缓存在内部 http 缓存中。 第二个请求是在缓存控制窗口内向 http://example.com 发出的。带有标题 application/xml。在这种情况下,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 :

If the selecting request header fields for the cached entry do not match the selecting request header fields of the new request, then the cache MUST NOT use a cached entry to satisfy the request unless it first relays the new request to the origin server in a conditional request and the server responds with 304 (Not Modified), including an entity tag or Content-Location that indicates the entity to be used.

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

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

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/

相关文章:

java - JMS主机和JMS服务器之间的区别

java - ViewResolver Spring 不工作

javascript - 遍历嵌套的 json 对象数组

android - 取消或覆盖在 Espresso 测试下的 Activity 中进行的 API 调用

java - 如何创建一个接受字符串并返回字符串中第二个字符的函数?

java - 原始字符串文字 - 删除前导缩进

python - 如何在将数据编码为 JSON 之前将数据从 SQLite 数据库中读取到字典中?

jquery - Grails-合并来自多个域的数据并返回 Controller

java - 在不缓冲整个事情的情况下记录 OkHttp 响应主体大小

java - OkHttp - 获取失败的响应正文