A good HTTP caching strategy can significantly improve the performance of Web applications and the experience of their clients. The main use of the "Cache-control" HTTP response header to complete, with conditional headers such as "last-modified" and "ETag."
The "Cache-control" HTTP response header suggests how private caches (such as browsers) and public caches (such as proxies) cache HTTP response for future reuse.
The "ETag" (Entity tag) is the HTTP response header returned by the http/1.1-compliant Web server, which is used to determine the contents of a given URL change. It can be considered a more complex successor to the "Last-modified" header. When the server returns a representation with an ETag header, the client can use the header in subsequent gets-in a "If-none_match" header. If the content does not change, the server returns "304:not Modified".
This section describes the possible ways to configure HTTP caching in a spring Web MVC application.
1. Cache-control HTTP Header
Spring WEB MVC supports many Cache-control headers that use environments and ways to configure an application. The RFC 7234 section 5.2.2 describes the header and its possible directives in detail, and there are several different ways to implement common cases.
Spring Web MVC uses a configuration convention in several of its APIs: setcacheperiod (int seconds):
- -1 means the Cache-control response header is not generated.
- 0 delegates will block the cache, using Cache-control:no-store directive.
- The n>0 caches the given response for n seconds, using cache-control:max-age=n directive.
The CacheControl construction class simply describes the available Cache-control directives, which makes it easier to build your own HTTP caching policy. Once constructed, a CacheControl instance can be used as a parameter in several spring Web MVC APIs.
// Cache for a hour-"cache-control:max-age= 3600 " CacheControl cccacheonehour = cachecontrol.maxage (1 // Prevent caching-"Cache-control:no-store" CacheControl ccnostore = Cachecontrol.nostore (); // Cache for ten days on public and private caches, // Public caches should not transform the response // "cache-control:max-age=864000, public, No-transform" CacheControl Cccustom = cachecontrol.maxage (10
2. HTTP caching support for static resources
Static resources should use the appropriate Cache-control and conditional headers to optimize performance. Configuring a Resourcehttprequesthandler to serve static resources will not only naturally write last-modified headers (by reading the metadata of the file), but also write Cache-control headers-- If it is configured correctly.
You can set Resourcehttprequesthandler Cacheperiod attribute or use a CacheControl instance, which can support more specific directives:
@Configuration @enablewebmvc Public class extends webmvcconfigureradapter { @Override publicvoid addresourcehandlers ( Resourcehandlerregistry registry) { Registry.addresourcehandler ("/resources/**") . Addresourcelocations ("/public-resources/") . Setcachecontrol (Cachecontrol.maxage (1, timeunit.hours). Cachepublic ());} }
In the XML:
<mapping= "/resources/**" location= "/public-resources/" > <max-age= "3600" cache-public= "true" /></mvc:resources>
3. Support Cache-control, ETAG, last-modified response headers in controllers
Controllers can support Cache-control, ETAG, and/or if-modified-since HTTP request, which is highly recommended if response has a Cache-control header set. This computes a lastmodified long and/or an ETag value for the given request, compares it to the If-modified-since request header value, and may return a status code 304 ( Not Modified) of response.
As described in the "Using Httpentity" section, controllers can use the Httpentity type to interact with Request/response.
The controllers that returns responseentity can contain HTTP caching information in responses as follows:
@GetMapping ("/book/{id}") public responseentity<book> showbook (@PathVariable Long ID) { = findbook (ID); = book.getversion (); return responseentity . OK () . CacheControl (Cachecontrol.maxage (timeunit.days)) // LastModified is also available . Body (book);}
This will not only include the ETag and Cache-control headers in the response, but will also convert the response to an empty response body HTTP 304 Not Modified response -- If the client sends a conditional headers that matches the caching information set by the controller.
A @requestmapping method may also want to support the same behavior. You can do this:
@RequestMapping PublicString Myhandlemethod (WebRequest WebRequest, model model) {LongLastModified =//1. Application-specific Calculation if(Request.checknotmodified (lastmodified)) {//2. Shortcut exit-no further processing necessary return NULL; } //3. Or otherwise further request processing, actually preparing contentModel.addattribute (...); return"Myviewname";}
Here are two key elements: Call Request.checknotmodified (lastmodified) and return null. The former sets the appropriate response status and headers before it returns true. The latter, combined with the former, will allow spring MVC to no longer process the request further.
Note that there are 3 variants:
- Request.checknotmodified (lastmodified) compares lastmodified and if-modified-since or If-unmodified-since request header.
- The request.checknotmodified (etag) compares the ETag and If-none-match request headers.
- Request.checknotmodified (ETag, lastmodified) both compare, meaning that two conditions should be valid.
When the conditional Get/head requests is received, checknotmodified checks to see if the resource has not been modified, and if not, it returns an HTTP 304 not Modified response.
In the case of Post/put/delete requests, checknotmodified will check if Resouce has not been modified, and if there is a change, an HTTP 409 precondition Failed response will be returned. To prevent concurrent modifications.
4. Shallow ETag Support
Support for Etags is provided by the servlet filter shallowetagheaderfilter. This is a simple servlet Filter and can therefore be used in conjunction with any web framework. Shallowetagheaderfilter filter Creates a shallow etags (as opposed to deep etags, which is spoken later). The filter caches the contents (or other content) of the rendered JSP, generates a MD5 hash, and returns it as an ETag header for response. When the next client requests the same resource, it uses that hash as If-none-match value. The filter detects it, re-renders the view, and compares the hashes of the two. If equal, returns 304.
Note that this strategy saves network bandwidth, not CPUs, because response is still required for each request. Other strategies at the controller level (as mentioned above) can save bandwidth and avoid calculations.
The filter has a Writeweaketag parameter, which is used to configure the filter to write weak etags, like this: as W/"02a2d595e6ed9a0b24f027f2b63b134d6"
defined in RFC 7232 section 2.3.
You can configure Shallowetagheaderfilter in Web. xml:
<Filter> <Filter-name>Etagfilter</Filter-name> <Filter-class>Org.springframework.web.filter.ShallowEtagHeaderFilter</Filter-class> <!--Optional parameter that configures the filter to write weak etags <init-param> <param-name>writ eweaketag</param-name> <param-value>true</param-value> </init-param> -</Filter><filter-mapping> <Filter-name>Etagfilter</Filter-name> <Servlet-name>Petclinic</Servlet-name></filter-mapping>
Or in a servlet 3.0+ environment:
Public class extends Abstractdispatcherservletinitializer { // ... @Override protected filter[] Getservletfilters () { return New New shallowetagheaderfilter ()};} }
See sections 22.15, "code-based Servlet container Initialization" for more details.
Official Documentation Links:
Http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-caching
Spring 4 Official Document Learning (11) HTTP caching support for the WEB MVC framework