Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
90ed0cf0
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
90ed0cf0
编写于
3月 23, 2015
作者:
B
Brian Clozel
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Document HTTP caching features in 4.2
Issue: SPR-11792
上级
7fa4ac1c
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
192 addition
and
35 deletion
+192
-35
src/asciidoc/web-mvc.adoc
src/asciidoc/web-mvc.adoc
+192
-35
未找到文件。
src/asciidoc/web-mvc.adoc
浏览文件 @
90ed0cf0
...
...
@@ -1911,39 +1911,6 @@ which case they apply to matching controllers. This provides an alternative to u
`WebBindingInitializer`. See the
<
<
mvc-ann-controller-advice
>
> section for more details.
[[mvc-ann-lastmodified]]
==== Support for the Last-Modified Response Header To Facilitate Content Caching
An `@RequestMapping` method may wish to support `'Last-Modified'` HTTP requests, as
defined in the contract for the Servlet API's `getLastModified` method, to facilitate
content caching. This involves calculating a lastModified `long` value for a given
request, comparing it against the `'If-Modified-Since'` request header value, and
potentially returning a response with status code 304 (Not Modified). An annotated
controller method can achieve that as follows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@RequestMapping
public String myHandleMethod(WebRequest webRequest, Model model) {
long lastModified = // 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 content
model.addAttribute(...);
return "myViewName";
}
----
There are two key elements to note: calling `request.checkNotModified(lastModified)` and
returning `null`. The former sets the response status to 304 before it returns `true`.
The latter, in combination with the former, causes Spring MVC to do no further
processing of the request.
[[mvc-ann-controller-advice]]
==== Advising controllers with the `@ControllerAdvice` annotation
The `@ControllerAdvice` annotation is a component annotation allowing implementation
...
...
@@ -4029,6 +3996,7 @@ You do not need to define a `DefaultRequestToViewNameTranslator` bean explicitly
like the default settings of the `DefaultRequestToViewNameTranslator`, you can rely on
the Spring Web MVC `DispatcherServlet` to instantiate an instance of this class if one
is not explicitly configured.
====
Of course, if you need to change the default settings, then you do need to configure
...
...
@@ -4038,9 +4006,16 @@ that can be configured.
[[mvc-caching]]
== HTTP caching support
A good HTTP caching strategy can significantly improve the performance of a web application
and the experience of its clients. The `'Cache-Control'` HTTP response header is mostly
responsible for this, along with conditional headers such as `'Last-Modified'` and `'ETag'`.
The `'Cache-Control'` HTTP response header advice private caches (e.g. browsers) and
public caches (e.g. proxies) on how they can cache HTTP responses for further reuse.
[[mvc-etag]]
== ETag support
An http://en.wikipedia.org/wiki/HTTP_ETag[ETag] (entity tag) is an HTTP response header
returned by an HTTP/1.1 compliant web server used to determine change in content at a
given URL. It can be considered to be the more sophisticated successor to the
...
...
@@ -4048,6 +4023,163 @@ given URL. It can be considered to be the more sophisticated successor to the
client can use this header in subsequent GETs, in an `If-None-Match` header. If the
content has not changed, the server returns `304: Not Modified`.
This section describes the different choices available to configure HTTP caching in a
Spring Web MVC application.
[[mvc-caching-cachecontrol]]
=== Cache-Control HTTP header
Spring Web MVC supports many use cases and ways to configure "Cache-Control" headers for
an application. While the https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234 Section 5.2.2]
completely describes that header and its possible directives, there are several ways to
address the most common cases.
Spring Web MVC is using a configuration convention in several of its APIs:
`setCachePeriod(int seconds)`:
* A `-1` value won't generate a `'Cache-Control'` response header
* A `0` value will prevent caching using the `'Cache-Control: no-store'` directive
* A `n > 0` value will cache the given response for `n` seconds using the
`'Cache-Control: max-age=n'` directive
The {javadoc-baseurl}/org/springframework/http/CacheControl.html[`CacheControl`] builder
class simply describes the available "Cache-Control" directives and makes it easier to
build your own HTTP caching strategy. Once built, a `CacheControl` instance can be then
taken as an argument in several Spring Web MVC APIs.
[source,java,indent=0]
[subs="verbatim,quotes"]
----
// 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();
----
[[mvc-caching-static-resources]]
=== HTTP caching support for static resources
Static resources should be served with appropriate `'Cache-Control'` and conditional
headers for optimal performance.
<
<
mvc-config-static-resources
,
Configuring
a
`
ResourceHttpRequestHandler
`
>
> for serving
static resources not only natively writes `'Last-Modified'` headers by reading files
metadata, but also `'Cache-Control'` if properly configured.
You can set the `cachePeriod` attribute on a `ResourceHttpRequestHandler` or use
a `CacheControl` instance, which supports more specific directives:
[source,java,indent=0]
[subs="verbatim"]
----
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public-resources/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic());
}
}
----
And in XML:
[source,xml,indent=0]
[subs="verbatim"]
----
<mvc:resources
mapping=
"/resources/**"
location=
"/public-resources/"
>
<mvc:cachecontrol
max-age=
"3600"
cache-public=
"true"
/>
</mvc:resources>
----
[[mvc-caching-etag-lastmodified]]
=== Support for the Cache-Control, ETag and Last-Modified response headers in Controllers
Controllers can support `'Cache-Control'` `'ETag'` and/or `'If-Modified-Since'` HTTP requests;
this is indeed recommended if a `'Cache-Control'` header is to be set on the response.
This involves calculating a lastModified `long` and/or an Etag value for a given request,
comparing it against the `'If-Modified-Since'` request header value, and potentially returning
a response with status code 304 (Not Modified).
As described in
<
<
mvc-ann-httpentity
>
>, Controllers can access request/response using `HttpEntity` types.
Controllers returning `ResponseEntity` can include HTTP caching information in responses like this:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@RequestMapping("/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);
}
----
Doing this will not only include `'ETag'` and `'Cache-Control'` headers in the response, it will **also convert the
response to a `HTTP 304 Not Modified` response with an empty body** if the conditional headers sent by the client
match the caching information set by the Controller.
An `@RequestMapping` method may also wish to support the same behavior.
This can be achieved as follows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@RequestMapping
public String myHandleMethod(WebRequest webRequest, Model model) {
long lastModified = // 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 content
model.addAttribute(...);
return "myViewName";
}
----
There are two key elements here: calling `request.checkNotModified(lastModified)` and
returning `null`. The former sets the response status to 304 before it returns `true`.
The latter, in combination with the former, causes Spring MVC to do no further
processing of the request.
Note that there are 3 variants for this:
* `request.checkNotModified(lastModified)` compares lastModified with the
`'If-Modified-Since'` request header
* `request.checkNotModified(eTag)` compares eTag with the `'ETag'` request header
* `request.checkNotModified(eTag, lastModified)` does both, meaning that both
conditions should be valid for the server to issue an `HTTP 304 Not Modified` response
[[mvc-httpcaching-shallowetag]]
=== Shallow ETag support
Support for ETags is provided by the Servlet filter `ShallowEtagHeaderFilter`. It is a
plain Servlet Filter, and thus can be used in combination with any web framework. The
`ShallowEtagHeaderFilter` filter creates so-called shallow ETags (as opposed to deep
...
...
@@ -4059,6 +4191,10 @@ compares the two hashes. If they are equal, a `304` is returned. This filter wil
save processing power, as the view is still rendered. The only thing it saves is
bandwidth, as the rendered response is not sent back over the wire.
Note that this strategy saves network bandwidth but not CPU, as the full response must be
computed for each request. Other strategies at the controller level (described above) can
save network bandwidth and avoid computation.
You configure the `ShallowEtagHeaderFilter` in `web.xml`:
[source,xml,indent=0]
...
...
@@ -4075,6 +4211,24 @@ You configure the `ShallowEtagHeaderFilter` in `web.xml`:
</filter-mapping>
----
Or in Servlet 3.0+ environments,
[source,java,indent=0]
[subs="verbatim,quotes"]
----
public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
// ...
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new ShallowEtagHeaderFilter() };
}
}
----
See
<
<
mvc-container-config
>
> for more details.
...
...
@@ -4656,6 +4810,9 @@ And in XML:
<mvc:resources
mapping=
"/resources/**"
location=
"/public-resources/"
cache-period=
"31556926"
/>
----
For more details, see
<
<
mvc-caching-static-resources
,
HTTP
caching
support
for
static
resources
>
>.
The `mapping` attribute must be an Ant pattern that can be used by
`SimpleUrlHandlerMapping`, and the `location` attribute must specify one or more valid
resource directory locations. Multiple resource locations may be specified using a
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录