HttpHeaderParser是Volley中的一个解析用的工具类,主要就是两个方法:parseCharset方法和parseCacheHeaders方法。
parseCharset方法的作用就是从“content-type”响应首部中解析出编码方式“charset”,如果解析不出来的话,就返回默认的编码方式“ISO-8859-1”。
parseCharset方法源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public static String parseCharset(Map<String, String> headers, String defaultCharset) { String contentType = headers.get(HTTP.CONTENT_TYPE); if (contentType != null) { String[] params = contentType.split(";"); for (int i = 1; i < params.length; i++) { String[] pair = params[i].trim().split("="); if (pair.length == 2) { if (pair[0].equals("charset")) { return pair[1]; } } } } return defaultCharset; } public static String parseCharset(Map<String, String> headers) { return parseCharset(headers, HTTP.DEFAULT_CONTENT_CHARSET); }
parseCacheHeaders作用就是根据服务器返回的各种响应首部,构建一个Cache.Entry对象供我们使用。
parseCacheHeaders的源码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 public static Cache.Entry parseCacheHeaders(NetworkResponse response) { long now = System.currentTimeMillis(); Map<String, String> headers = response.headers; long serverDate = 0; long lastModified = 0; long serverExpires = 0; long softExpire = 0; long finalExpire = 0; long maxAge = 0; long staleWhileRevalidate = 0; boolean hasCacheControl = false; boolean mustRevalidate = false; String serverEtag = null; String headerValue; headerValue = headers.get("Date"); if (headerValue != null) { serverDate = parseDateAsEpoch(headerValue); } headerValue = headers.get("Cache-Control"); if (headerValue != null) { hasCacheControl = true; String[] tokens = headerValue.split(","); for (int i = 0; i < tokens.length; i++) { String token = tokens[i].trim(); if (token.equals("no-cache") || token.equals("no-store")) { return null; } else if (token.startsWith("max-age=")) { try { maxAge = Long.parseLong(token.substring(8)); } catch (Exception e) { } } else if (token.startsWith("stale-while-revalidate=")) { try { staleWhileRevalidate = Long.parseLong(token.substring(23)); } catch (Exception e) { } } else if (token.equals("must-revalidate") || token.equals("proxy-revalidate")) { mustRevalidate = true; } } } headerValue = headers.get("Expires"); if (headerValue != null) { serverExpires = parseDateAsEpoch(headerValue); } headerValue = headers.get("Last-Modified"); if (headerValue != null) { lastModified = parseDateAsEpoch(headerValue); } serverEtag = headers.get("ETag"); if (hasCacheControl) { softExpire = now + maxAge * 1000; finalExpire = mustRevalidate ? softExpire : softExpire + staleWhileRevalidate * 1000; } else if (serverDate > 0 && serverExpires >= serverDate) { softExpire = now + (serverExpires - serverDate); finalExpire = softExpire; } Cache.Entry entry = new Cache.Entry(); entry.data = response.data; entry.etag = serverEtag; entry.softTtl = softExpire; entry.ttl = finalExpire; entry.serverDate = serverDate; entry.lastModified = lastModified; entry.responseHeaders = headers; return entry; } public static long parseDateAsEpoch(String dateStr) { try { // Parse date in RFC1123 format if this header contains one return DateUtils.parseDate(dateStr).getTime(); } catch (DateParseException e) { // Date in invalid format, fallback to 0 return 0; } }
根据Date首部,解析出serverDate,也就是服务器响应的日期。
1 2 3 4 headerValue = headers.get("Date"); if (headerValue != null) { serverDate = parseDateAsEpoch(headerValue); }
根据Expires首部,解析出serverExpires,也就是缓存数据的过期时间。
1 2 3 4 headerValue = headers.get("Expires"); if (headerValue != null) { serverExpires = parseDateAsEpoch(headerValue); }
根据Last-Modified首部,解析出lastModified,也就是服务器端返回的数据的最后修改日期。在Volley中当缓存数据过期的时候,会用到这个值发起条件请求。
1 2 3 4 headerValue = headers.get("Last-Modified"); if (headerValue != null) { lastModified = parseDateAsEpoch(headerValue); }
获取数据的ETag值,ETag值相当于数据的身份证,ETag值不同,说明数据不同。在Volley中当缓存数据过期的时候,会用到这个值发起条件请求。
1 serverEtag = headers.get("ETag");
上一篇:Volley-StringRequest源码解析
下一篇:Volley-NetworkResponse源码解析