21.14.4 弱ETag(Shallow ETag)

对ETag的支持是由Servlet的过滤器ShallowEtagHeaderFilter提供的。它是纯Servlet技术实现的过滤器,因此,它可以与任何web框架无缝集成。ShallowEtagHeaderFilter过滤器会创建一个我们称为弱ETag(与强ETag相对,后面会详述)的对象。过滤器会将渲染的JSP页面的内容(包括其他类型的内容)缓存起来,然后以此生成一个MD5哈希值,并把这个值作为ETag头的值写回响应中。下一次客户端再次请求这个同样的资源时,它会将这个ETag的值写到If-None-Match头中。过滤器会检测到这个请求头,然后再次把视图渲染出来并比较两个哈希值。如果比较的结果是相同的,那么服务器会返回一个304。正如你所见,视图仍然会被渲染,因此本质上这个过滤器并非节省任何计算资源。唯一节省的东西,是带宽,因为被渲染的响应不会被整个发送回客户端。

请注意,这个策略节省的是网络带宽,而非CPU。因为对于每个请求,完整的响应仍然需要被整个计算出来。而其他在控制器层级实现的策略(上几节所述的)可以同时节省网络带宽及避免多余计算。

你可以在web.xml中配置ShallowEtagHeaderFilter

  1. <filter>
  2. <filter-name>etagFilter</filter-name>
  3. <filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>etagFilter</filter-name>
  7. <servlet-name>petclinic</servlet-name>
  8. </filter-mapping>

如果是在Servlet 3.0以上的环境下,可以这么做:

  1. public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
  2. // ...
  3. @Override
  4. protected Filter[] getServletFilters() {
  5. return new Filter[] { new ShallowEtagHeaderFilter() };
  6. }
  7. }

更多配置细节,请参考第21.15 基于代码的Servlet容器初始化一小节。