JJD*_*JJD 9 response http-caching http-headers retrofit okhttp
我用来避免解析遍地的服务器响应,如果它也不会改变通过计算响应的哈希值:
public class HttpClient {
protected OkHttpClient mClient = new OkHttpClient();
public String get(final URL url, final String[] responseHash)
throws IOException {
HttpURLConnection connection = new OkUrlFactory(mClient).open(url);
InputStream inputStream = null;
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
assert messageDigest != null;
try {
// Read the response.
inputStream = connection.getInputStream();
byte[] response = readFully(inputStream);
final byte[] digest = messageDigest.digest(response);
responseHash[0] = Base64.encodeToString(digest, Base64.DEFAULT);
return new String(response, Util.UTF_8);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
private byte[] readFully(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int count; (count = in.read(buffer)) != -1; ) {
out.write(buffer, 0, count);
}
return out.toByteArray();
}
}
Run Code Online (Sandbox Code Playgroud)
这是响应头:
HTTP/1.1 200 OK
Server: Apache/2.4.10 (Linux/SUSE)
X-Powered-By: PHP/5.4.20
X-UA-Compatible: IE=edge
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Expires: Thu, 08 Oct 2015 16:15:09 +0000
X-Frame-Options: SAMEORIGIN
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Date: Wed, 07 Oct 2015 16:15:09 GMT
X-Varnish: 505284843
Age: 0
Via: 1.1 varnish
Connection: keep-alive
Run Code Online (Sandbox Code Playgroud)
现在我切换到Retrofit,我想知道什么是避免解析相同响应的优雅方法?是拦截要走的路?我不负责服务器后端,也不能修改它.
您可以使用 Expires 标头进行缓存控制,这样就可以避免不必要的下载。我认为这不是一个好的方法,但在这种情况下,由于您无法控制服务器端,所以这是我现在能想到的唯一方法。
\n\n\n\n\n实体的过期时间可以由源服务器使用 Expires 头来指定(参见第 14.21 节)。或者,可以在响应中使用 max-age 指令来指定它。当缓存的响应中存在 max-age\n 缓存控制指令时,如果响应的当前年龄大于新请求时给定的年龄值(以秒为单位),则该响应已过时资源。响应上的 max-age\n 指令意味着该响应是可缓存的(即\n“公共”),除非还存在其他一些更具限制性的缓存指令。
\n\n如果响应同时包含 Expires 标头和 max-age 指令,则 max-age 指令将覆盖 Expires 标头,即使 Expires 标头限制性更强。对于给定的响应,此规则允许源服务器为 HTTP/1.1(或更高版本)缓存提供比 HTTP/1.0 缓存更长的过期时间。如果某些 HTTP/1.0 缓存无法正确计算年龄或过期时间(可能是由于时钟不同步),这可能会很有用。
\n\n许多 HTTP/1.0 缓存实现会将小于或等于响应日期值的 Expires 值视为与 Cache-Control 响应指令“no-cache”等效。如果 HTTP/1.1 缓存收到这样的响应,并且该响应不包含 Cache-Control 标头字段,则它应该考虑该响应是不可缓存的,以便保持与 HTTP/1.0 服务器的兼容性。
\n\n注意:源服务器可能希望在网络上使用相对较新的 HTTP 缓存控制功能,例如“private”指令,包括不理解该功能的旧缓存。源服务器需要将新功能与 Expires 字段相结合,该字段的值小于或等于 Date 值。这将防止较旧的缓存不正确地缓存响应。
\n
有不同的方法。我用这个:
\n\n您可以使用RequestInterceptor来执行此操作,正如您所指出的:
public class HeaderRequestInterceptor implements RequestInterceptor {\n\n private final static String TAG = \n HeaderRequestInterceptor.class.getSimpleName();\n\n private SharedPreferences mPreferences;\n\n public HeaderRequestInterceptor() {\n mPreferences = PreferenceManager.getDefaultSharedPreferences(\n DaoApplication.getAppContext());\n }\n\n @Override\n public void intercept(RequestFacade request) {\n String etagValue = mPreferences.getString(EtagConfig.MY_ETAG_VALUE, "");\n request.addHeader("If-None-Match", etagValue);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n示例输出:
\n\nRetrofit D ---> HTTP GET https://url.irontec.com/rest/schedule\n D If-None-Match:\n D Authorization: MyToken M2JiOGQwZGNjNWJiNWNiOTA1Yjc3YTA0YTAyMzEwYWY6OjIwMTUtMTAtMDhUMTM6MDc6MDMrMDA6MDA=\n D Connection: close\n\nRetrofit D <--- HTTP 200 https://url.irontec.com/rest/schedule (559ms)\n D : HTTP/1.1 200 OK\n D Access-Control-Allow-Credentials: true\n D Access-Control-Allow-Headers: Authorization, Origin, Content-Type, X-CSRF-Token\n D Access-Control-Allow-Methods: GET, PUT, POST, OPTIONS, DELETE\n D Access-Control-Allow-Origin: *\n D Connection: close\n D Content-Type: application/json; charset=UTF-8;\n D Date: Thu, 08 Oct 2015 13:07:07 GMT\n D Etag: a3145c3f85f2dca1c78f87107331c766\n D Server: Apache\n D Transfer-Encoding: chunked\n D X-Android-Received-Millis: 1444309624169\n D X-Android-Response-Source: NETWORK 200\n D X-Android-Sent-Millis: 1444309623870\n D X-Content-Type-Options: nosniff\n D X-Frame-Options: sameorigin\nRun Code Online (Sandbox Code Playgroud)\n\n现在刷新内容时:
\n\nRetrofit D ---> HTTP GET https://url.irontec.com/rest/schedule\n D If-None-Match: a3145c3f85f2dca1c78f87107331c766\n D Authorization: MyToken MGQ1OWM4YjViYTMxZWM3OGRmMDBlYTZjNmFjNDY3MmI6OjIwMTUtMTAtMDhUMTM6MTA6MDkrMDA6MDA=\n D Connection: close\n D ---> END HTTP (no body)\n\nRetrofit D <--- HTTP 304 https://url.irontec.com/rest/schedule (299ms)\n D : HTTP/1.1 304 Not Modified\n D Connection: close\n D Date: Thu, 08 Oct 2015 13:10:12 GMT\n D Server: Apache\n D X-Android-Received-Millis: 1444309809335\n D X-Android-Response-Source: NETWORK 304\n D X-Android-Sent-Millis: 1444309809163\n D <--- END HTTP (0-byte body)\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1762 次 |
| 最近记录: |