The onFailure callback and future.get() occur in different threads so
this change adds a latch to ensure we have both before asserting.
Issue: SPR-12887
AbstractHttpMessageConverter now tries to call getDefaultContentType
with the actual value to be converted to see if that will result in
a more concrete mediat type than application/octet-stream.
Issue: SPR-12894
This commit introduces support for CORS in Spring Framework.
Cross-origin resource sharing (CORS) is a mechanism that allows
many resources (e.g. fonts, JavaScript, etc.) on a web page to
be requested from another domain outside the domain from which
the resource originated. It is defined by the CORS W3C
recommandation (http://www.w3.org/TR/cors/).
A new annotation @CrossOrigin allows to enable CORS support
on Controller type or method level. By default all origins
("*") are allowed.
@RestController
public class SampleController {
@CrossOrigin
@RequestMapping("/foo")
public String foo() {
// ...
}
}
Various @CrossOrigin attributes allow to customize the CORS configuration.
@RestController
public class SampleController {
@CrossOrigin(origin = { "http://site1.com", "http://site2.com" },
allowedHeaders = { "header1", "header2" },
exposedHeaders = { "header1", "header2" },
method = RequestMethod.DELETE,
maxAge = 123, allowCredentials = "true")
@RequestMapping(value = "/foo", method = { RequestMethod.GET, RequestMethod.POST} )
public String foo() {
// ...
}
}
A CorsConfigurationSource interface can be implemented by HTTP request
handlers that want to support CORS by providing a CorsConfiguration
that will be detected at AbstractHandlerMapping level. See for
example ResourceHttpRequestHandler that implements this interface.
Global CORS configuration should be supported through ControllerAdvice
(with type level @CrossOrigin annotated class or class implementing
CorsConfigurationSource), or with XML namespace and JavaConfig
configuration, but this is not implemented yet.
Issue: SPR-9278
This commit adds a filters property to MappingJacksonValue
and also manages a special FilterProvider class name model key in
order to be able to specify a customized FilterProvider for each
handler method execution, and thus provides a more dynamic
alternative to our existing JsonView support.
A filters property is also now available in Jackson2ObjectMapperBuilder
and Jackson2ObjectMapperFactoryBean in order to set easily a
global FilterProvider.
More details about @JsonFilter at
http://wiki.fasterxml.com/JacksonFeatureJsonFilter.
Issue: SPR-12586
This commit introduces support for "Path Segment URI Variable
expansion", see https://tools.ietf.org/html/rfc6570#section-3.2.6.
In practice, this means that URI template variables prefixed with a '/'
are treated like path segments and - as such - will encode any '/'
found. For example: {/foo} expanded with "bar/baz" with result in
"bar%2F".
Issue: SPR-12750
This reverts commit a57d42829c after the
realization of a weaknesses with the proposed approach.
For example if a path segment contains both a /-prefixed and a regular
URI variable, there is no way to split that into a sequence of path
and path segments. The solution will have to be on the side of
UriComponents at the time of encoding.
Prior to this commit, Cache-Control HTTP headers could be set using
a WebContentInterceptor and configured cache mappings.
This commit adds support for cache-related HTTP headers at the controller
method level, by returning a ResponseEntity instance:
ResponseEntity.status(HttpStatus.OK)
.cacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic())
.eTag("deadb33f8badf00d")
.body(entity);
Also, this change now automatically checks the "ETag" and
"Last-Modified" headers in ResponseEntity, in order to respond HTTP
"304 - Not Modified" if necessary.
Issue: SPR-8550
This commit improves HTTP caching defaults and flexibility in
Spring MVC.
1) Better default caching headers
The `WebContentGenerator` abstract class has been updated with
better HTTP defaults for HTTP caching, in line with current
browsers and proxies implementation (wide support of HTTP1.1, etc);
depending on the `setCacheSeconds` value:
* sends "Cache-Control: max-age=xxx" for caching responses and
do not send a "must-revalidate" value by default.
* sends "Cache-Control: no-store" or "Cache-Control: no-cache"
in order to prevent caching
Other methods used to set specific header such as
`setUseExpiresHeader` or `setAlwaysMustRevalidate` are now deprecated
in favor of `setCacheControl` for better flexibility.
Using one of the deprecated methods re-enables previous HTTP caching
behavior.
This change is applied in many Handlers, since
`WebContentGenerator` is extended by `AbstractController`,
`WebContentInterceptor`, `ResourceHttpRequestHandler` and others.
2) New CacheControl builder class
This new class brings more flexibility and allows developers
to set custom HTTP caching headers.
Several strategies are provided:
* `CacheControl.maxAge(int)` for caching responses with a
"Cache-Control: max-age=xxx" header
* `CacheControl.noStore()` prevents responses from being cached
with a "Cache-Control: no-store" header
* `CacheControl.noCache()` forces caches to revalidate the cached
response before reusing it, with a "Cache-Control: no-store" header.
From that point, it is possible to chain method calls to craft a
custom CacheControl instance:
```
CacheControl cc = CacheControl.maxAge(1, TimeUnit.HOURS)
.cachePublic().noTransform();
```
3) Configuring HTTP caching in Resource Handlers
On top of the existing ways of configuring caching mechanisms,
it is now possible to use a custom `CacheControl` to serve
resources:
```
@Configuration
public class MyWebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
CacheControl cc = CacheControl.maxAge(1, TimeUnit.HOURS);
registry.addResourceHandler("/resources/**)
.addResourceLocations("classpath:/resources/")
.setCacheControl(cc);
}
}
```
or
```
<mvc:resources mapping="/resources/**" location="classpath:/resources/">
<mvc:cachecontrol max-age="3600" cache-public="true"/>
</mvc:resources>
```
Issue: SPR-2779, SPR-6834, SPR-7129, SPR-9543, SPR-10464
This change improves the following use cases with
`WebRequest.checkNotModified(String etag)` and
`WebRequest.checkNotModified(long lastModifiedTimeStamp)`:
1) Allow weak comparisons for ETags
Per rfc7232 section-2.3, ETags can be strong or weak;
this change allows comparing weak forms `W/"etagvalue"` but does
not make a difference between strong and weak comparisons.
2) Allow multiple ETags in client requests
HTTP clients can send multiple ETags values in a single header such as:
`If-None-Match: "firstvalue", "secondvalue"`
This change makes sure each value is compared to the one provided by
the application side.
3) Extended support for ETag values
This change adds padding `"` to the ETag value provided by
the application, if not already done:
`etagvalue` => `"etagvalue"`
It also supports wildcard values `*` that can be sent by HTTP clients.
4) Sending validation headers for 304 responses
As defined in https://tools.ietf.org/html/rfc7232#section-4.1
`304 Not Modified` reponses must generate `Etag` and `Last-Modified`
HTTP headers, as they would have for a `200 OK` response.
5) Providing a new method to validate both Etag & Last-Modified
Also, this change adds a new method
`WebRequest.checkNotModified(String etag, long lastModifiedTimeStamp)`
in order to support validation of both `If-None-Match` and
`Last-Modified` headers sent by HTTP clients, if both values are
supported by the application code.
Even though this approach is recommended by the HTTP rfc (setting both
Etag and Last-Modified headers in the response), this requires more
application logic and may not apply to all resources produced by the
application.
Issue: SPR-11324
This commit introduces support for HTTP byte ranges in the
ResourceHttpRequestHandler. This support consists of a number of
changes:
- Parsing of HTTP Range headers in HttpHeaders, using a new HttpRange
class and inner ByteRange/SuffixByteRange subclasses.
- MIME boundary generation moved from FormHttpMessageConverter to
MimeTypeUtils.
- writePartialContent() method introduced in ResourceHttpRequestHandler,
handling the byte range logic
- Additional partial content tests added to
ResourceHttpRequestHandlerTests.
Issue: SPR-10805
After this change UriComponentsBuilder#uriComponents method no longer
no longer copies from the given UriComponents but rather lets the
UriComponents instance copy itself to the UriComponentsBuilder.
This avoids the need for instanceof checks and also makes it possible
to distinguish between path and path segments, which otherwise is
internal knowledge of UriComponentsBuilder.
Issue: SPR-12742
Revised HandlerMethod.getBeanType() impl for both web and messaging.
In addition, HandlerMethods get created with the internal BeanFactory now.
Issue: SPR-12832
Prior to this commit, the ContentCachingRequestWrapper would immediately
consume the wrapped request's InputStream when asked for the cached
content; that caused several issues:
* the request body was read in memory even if it wasn't yet consumed by
the application, leading to inefficiencies.
* when requesting the InputStream, an empty InputStream was returned
since the original was already read.
This case only happened for form POSTs requests.
This commit makes sure that the wrapper does not alter the request
expected behavior:
* when getting the inputstream, it is wrapped in order to cache its
content
* when getting request parameters, the request body is cached and its
inputstream is consumed, as expected
Issue: SPR-12810
All HttpMessageConverters should support StreamingHttpOutputMessage.
Specifically, the BufferedImageHttpMessageConverter and
FormHttpMessageConverter should do so.
Issue: SPR-12715