1.8 HTTP Caching

HTTP缓存可以显着提高Web应用程序的性能。 HTTP缓存围绕Cache-Control响应标头以及随后的条件请求标头(例如Last-Modified和ETag)。 缓存控制为私有(例如浏览器)和公共(例如代理)缓存提供有关如何缓存和重用响应的建议。 ETag标头用于发出条件请求,如果内容未更改,则可能导致没有主体的304(NOT_MODIFIED)。 ETag可以看作是Last-Modified头的更复杂的后继者。

本节描述了Spring Web MVC中与HTTP缓存相关的选项。

1.8.1 CacheControl

CacheControl支持配置与Cache-Control标头相关的设置,并在许多地方作为参数被接受:

  • WebContentInterceptor

  • WebContentGenerator

  • 控制器

  • 静态资源

尽管RFC 7234描述了Cache-Control响应标头的所有可能的指令,但CacheControl类型采用了面向用例的方法,着重于常见方案:

// Cache for an hour - "Cache-Control: max-age=3600"
CacheControl ccCacheOneHour = CacheControl.maxAge(1, TimeUnit.HOURS);

// Prevent caching - "Cache-Control: no-store"
CacheControl ccNoStore = CacheControl.noStore();

// Cache for ten days in public and private caches,
// public caches should not transform the response
// "Cache-Control: max-age=864000, public, no-transform"
CacheControl ccCustom = CacheControl.maxAge(10, TimeUnit.DAYS).noTransform().cachePublic();

WebContentGenerator还接受一个更简单的cachePeriod属性(以秒为单位定义),该属性的工作方式如下:

  • -1值不会生成Cache-Control响应标头。

  • 值为0可以防止使用“ Cache-Control:无存储”指令进行缓存。

  • n> 0值通过使用'Cache-Control:max-age = n'指令将给定响应缓存n秒。

1.8.2 控制器

控制器可以添加对HTTP缓存的显式支持。 我们建议您这样做,因为需要先计算资源的lastModified或ETag值,然后才能将其与条件请求标头进行比较。 控制器可以将ETag标头和Cache-Control设置添加到ResponseEntity,如以下示例所示:

@GetMapping("/book/{id}")
public ResponseEntity<Book> showBook(@PathVariable Long id) {

    Book book = findBook(id);
    String version = book.getVersion();

    return ResponseEntity
            .ok()
            .cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS))
            .eTag(version) // lastModified is also available
            .body(book);
}

如果与条件请求标头的比较表明内容未更改,则前面的示例发送带有空主体的304(NOT_MODIFIED)响应。 否则,ETag和Cache-Control标头将添加到响应中。

您还可以在控制器中针对条件请求标头进行检查,如以下示例所示:

@RequestMapping
public String myHandleMethod(WebRequest webRequest, Model model) {

    long eTag = ... 

    if (request.checkNotModified(eTag)) {
        return null; 
    }

    model.addAttribute(...); 
    return "myViewName";
}

可以使用三种变体来检查针对eTag值,lastModified值或两者的条件请求。 对于有条件的GET和HEAD请求,可以将响应设置为304(NOT_MODIFIED)。 对于条件POST,PUT和DELETE,您可以将响应设置为409(PRECONDITION_FAILED),以防止并发修改。

1.8.3 Static Resources

您应该将静态资源与Cache-Control和条件响应标头一起提供,以实现最佳性能。 请参阅有关配置静态资源的部分。

1.8.4 ETag Filter

您可以使用ShallowEtagHeaderFilter添加从响应内容计算得出的“shallow” eTag值,从而节省带宽,但不节省CPU时间。 请参阅浅ETag。

最后更新于