[关闭]
@946898963 2018-05-18T11:29:43.000000Z 字数 3337 阅读 1165

Volley-HttpHeaderParser源码解析

Android控件跟框架 Android源码分析


HttpHeaderParser是Volley中的一个解析用的工具类,主要就是两个方法:parseCharset方法和parseCacheHeaders方法。

parseCharset方法的作用就是从“content-type”响应首部中解析出编码方式“charset”,如果解析不出来的话,就返回默认的编码方式“ISO-8859-1”。

parseCharset方法源码如下:

  1. public static String parseCharset(Map<String, String> headers, String defaultCharset) {
  2. String contentType = headers.get(HTTP.CONTENT_TYPE);
  3. if (contentType != null) {
  4. String[] params = contentType.split(";");
  5. for (int i = 1; i < params.length; i++) {
  6. String[] pair = params[i].trim().split("=");
  7. if (pair.length == 2) {
  8. if (pair[0].equals("charset")) {
  9. return pair[1];
  10. }
  11. }
  12. }
  13. }
  14. return defaultCharset;
  15. }
  16. public static String parseCharset(Map<String, String> headers) {
  17. return parseCharset(headers, HTTP.DEFAULT_CONTENT_CHARSET);
  18. }

parseCacheHeaders作用就是根据服务器返回的各种响应首部,构建一个Cache.Entry对象供我们使用。

parseCacheHeaders的源码如下所示:

  1. public static Cache.Entry parseCacheHeaders(NetworkResponse response) {
  2. long now = System.currentTimeMillis();
  3. Map<String, String> headers = response.headers;
  4. long serverDate = 0;
  5. long lastModified = 0;
  6. long serverExpires = 0;
  7. long softExpire = 0;
  8. long finalExpire = 0;
  9. long maxAge = 0;
  10. long staleWhileRevalidate = 0;
  11. boolean hasCacheControl = false;
  12. boolean mustRevalidate = false;
  13. String serverEtag = null;
  14. String headerValue;
  15. headerValue = headers.get("Date");
  16. if (headerValue != null) {
  17. serverDate = parseDateAsEpoch(headerValue);
  18. }
  19. headerValue = headers.get("Cache-Control");
  20. if (headerValue != null) {
  21. hasCacheControl = true;
  22. String[] tokens = headerValue.split(",");
  23. for (int i = 0; i < tokens.length; i++) {
  24. String token = tokens[i].trim();
  25. if (token.equals("no-cache") || token.equals("no-store")) {
  26. return null;
  27. } else if (token.startsWith("max-age=")) {
  28. try {
  29. maxAge = Long.parseLong(token.substring(8));
  30. } catch (Exception e) {
  31. }
  32. } else if (token.startsWith("stale-while-revalidate=")) {
  33. try {
  34. staleWhileRevalidate = Long.parseLong(token.substring(23));
  35. } catch (Exception e) {
  36. }
  37. } else if (token.equals("must-revalidate") || token.equals("proxy-revalidate")) {
  38. mustRevalidate = true;
  39. }
  40. }
  41. }
  42. headerValue = headers.get("Expires");
  43. if (headerValue != null) {
  44. serverExpires = parseDateAsEpoch(headerValue);
  45. }
  46. headerValue = headers.get("Last-Modified");
  47. if (headerValue != null) {
  48. lastModified = parseDateAsEpoch(headerValue);
  49. }
  50. serverEtag = headers.get("ETag");
  51. if (hasCacheControl) {
  52. softExpire = now + maxAge * 1000;
  53. finalExpire = mustRevalidate
  54. ? softExpire
  55. : softExpire + staleWhileRevalidate * 1000;
  56. } else if (serverDate > 0 && serverExpires >= serverDate) {
  57. softExpire = now + (serverExpires - serverDate);
  58. finalExpire = softExpire;
  59. }
  60. Cache.Entry entry = new Cache.Entry();
  61. entry.data = response.data;
  62. entry.etag = serverEtag;
  63. entry.softTtl = softExpire;
  64. entry.ttl = finalExpire;
  65. entry.serverDate = serverDate;
  66. entry.lastModified = lastModified;
  67. entry.responseHeaders = headers;
  68. return entry;
  69. }
  70. public static long parseDateAsEpoch(String dateStr) {
  71. try {
  72. // Parse date in RFC1123 format if this header contains one
  73. return DateUtils.parseDate(dateStr).getTime();
  74. } catch (DateParseException e) {
  75. // Date in invalid format, fallback to 0
  76. return 0;
  77. }
  78. }

根据Date首部,解析出serverDate,也就是服务器响应的日期。

  1. headerValue = headers.get("Date");
  2. if (headerValue != null) {
  3. serverDate = parseDateAsEpoch(headerValue);
  4. }

根据Expires首部,解析出serverExpires,也就是缓存数据的过期时间。

  1. headerValue = headers.get("Expires");
  2. if (headerValue != null) {
  3. serverExpires = parseDateAsEpoch(headerValue);
  4. }

根据Last-Modified首部,解析出lastModified,也就是服务器端返回的数据的最后修改日期。在Volley中当缓存数据过期的时候,会用到这个值发起条件请求。

  1. headerValue = headers.get("Last-Modified");
  2. if (headerValue != null) {
  3. lastModified = parseDateAsEpoch(headerValue);
  4. }

获取数据的ETag值,ETag值相当于数据的身份证,ETag值不同,说明数据不同。在Volley中当缓存数据过期的时候,会用到这个值发起条件请求。

  1. serverEtag = headers.get("ETag");
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注