Prior to this commit, HTTP clients relying on the JDK HTTP client would
not properly reuse existing TCP connections (i.e. HTTP 1.1 persisten
connection). The SimpleClientHttpResponse would close the actual connection once the
response is handled.
As explained in the JDK documentation
(http://docs.oracle.com/javase/8/docs/technotes/guides/net/http-keepalive.html)
HTTP clients should do the following to allow resource reuse:
* consume the whole HTTP response content
* close the response inputstream once done
This commit makes sure that the response content is
totally drained and then the stream closed (and not the connection).
Issue: SPR-14040
Prior to this commit, binding a `@ModelAttribute` object as a Controller
handler paramater would instantiate the object and set all its
properties, fetching data from the request. When no data is available,
the WebDataBinder tries to bind default "empty" values:
* Boolean.FALSE for boolean types
* empty arrays for array types
* null by default
This commit adds the new default empty values:
* empty Collections for Collection types
* empty Maps for Map types
Rather than using empty implementations provided by `Collections.empty`
(which are not mutable), we're using the closest possible target type
and real implementations, provided by the `CollectionFactory`.
Issue: SPR-13502
Prior to this commit, HTTP Range requests were only supported by the
ResourceHttpRequestHandler when serving static resources.
This commit improves the ResourceHttpMessageConverter that
now supports partial writes of Resources.
For this, the `HttpEntityMethodProcessor` and
`RequestResponseBodyMethodProcessor` now wrap resources with HTTP
range information in a `HttpRangeResource`, if necessary. The
message converter handle those types and knows how to handle partial
writes.
Controller methods can now handle Range requests for
return types that extend Resource or HttpEntity:
@RequestMapping("/example/video.mp4")
public Resource handler() { }
@RequestMapping("/example/video.mp4")
public HttpEntity<Resource> handler() { }
Issue: SPR-13834
The DefaulUriTemplateHandler now provides a strictEncoding property
which if turned on encodes everything outside the reserved char set.
This is in contrast to the default policy of encoding only illegal
charaters depending on the URI component type.
Issue: SPR-11652
The new Filter is simply a new way of packaging the ability to extract
X-Forwarded-* headers already available via UriComponentsBuilder.
The Filter wraps the request and the effect is that anything using the
request will see the original schem, host, and port.
Issue: SPR-13614
Prior to this commit, `ServletWebRequest.checkNotModified` would only
support conditional GET/HEAD requests with "If-Modified-Since" and/or
"If-None-Match" request headers. In those cases, the server would return
"HTTP 304 Not Modified" responses if the resource didn't change.
This commit adds support for conditional update requests, such as
POST/PUT/DELETE requests with "If-Unmodified-Since" request headers.
If the underlying resource has been modified since the specified date,
the server will return a "409 Precondition failed" response status
to prevent concurrent updates.
Even if the modification status of the resource is reversed here
(modified vs. not modified), we're keeping here the same intent for the
return value, which signals if the response requires more processing or
if the handler method can return immediately:
```
if (request.checkNotModified(lastModified)) {
// shortcut exit - no further processing necessary
return null;
}
```
Issue: SPR-13863
This commit adds weak ETag support in ShallowEtagHeaderFilter.
This improves the behavior of the filter in tow ways:
* weak ETags in request headers such as `W/"0badc0ffee"` will be
compared with a "weak comparison" (matching both weak and strong ETags
of the same value)
* when enabled with the "writeWeakETag" init param, the filter will
write weak Etags in its HTTP responses
Issue: SPR-13778
AbstractJackson2HttpMessageConverter now implements its own
TypeVariable resolution algorithm since in Jackson 2.7 it is now
deprecated and has not the same behavior .
See https://github.com/FasterXML/jackson-databind/issues/1087
for more details.
The dependency on jackson-datatype-jdk7 has been removed since
it is now provided by default in the jackson-databind module.
Issues: SPR-13483, SPR-13728
Since ListenableFuture callbacks are invoked after the future is set,
we cannot rely on callbacks having taken place right after a call
to future.get(). This change adds a CountdownLatch to detect when
the callbacks were invoked.
Issue: SPR-12538
AsyncRequestExecution now properly supports decoration of the
request (URI, HTTP method, and headers).
Removed a no-op IdentityListenableFutureAdapter.
Use Spring Framework coding style.
Issue: SPR-12538
Fixed a bug where the URL content negotiation "format" parameter values
were case sensitive and only lowercase values were accepted. For
example, URL query parameter format=json returned the appropriate JSON
response but format=JSON resulted in a
HttpMediaTypeNotAcceptableException and returned:
406 - The resource identified by this request is only capable of
generating responses with characteristics not acceptable according to
the request "accept" headers.
When the MappingMediaTypeFileExtensionResolver is constructed, it is
passed a map containing the media type key to MediaType mappings
defined in the ContentNegotiationConfigurer. In the constructor of
MappingMediaTypeFileExtensionResolver, the keys are converted to
lowercase and the mappings of keys to MediaTypes are added to the
ConcurrentMap<String, MediaType> mediaTypes using the lowercase
version of the keys. However, when retrieving the MediaType from a key
in the lookupMediaType method, no conversion to lowercase is performed
so any value for the URL "format" parameter other than the lowercase
version will not return the proper MediaType result.
On May 1st, 2014, a change was made to
ParameterContentNegotiationStrategy to handle cases where the content
negotiation format URL parameter does not result in a match for a
MediaType. If no match is found, a HttpMediaTypeNotAcceptableException
is thrown resulting in the 406 response above. Prior to this commit, a
null was returned instead of throwing an exception so this issue was
hidden and appeared to function correctly.
To make the media type lookup case insensitive, added a line to the
lookupMediaType method in MediaTypeFileExtensionResolver to first
convert the extension (media type key) to lowercase prior to attempting
to retrieve it from the mediaTypes map.
Issue: SPR-13747
The recent commit 971f04 replaced the use of a NAMES_PATTERN regex in
favor of direct parsing in order to deal with nested curly braces.
The change also incorrectly replicated this logic which removes a
trailing slash after Pattern quoting (and not before):
cca037a74d/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java (L207-L210)
After some more investigation there doesn't appear to be any scenario
where the quoted pattern would end with a trailing slash. It should
always end with \E (end of quote) or a ")" (end of group). Nor are
there any failing tests so this commit removes the logic altogether.
Issue: SPR-13705
Prior to this commit, when adding a ShallowEtagHeaderFilter to an
application, the ServletResponse would be wrapped by a
ContentCachingResponseWrapper. When any part of the Spring
infrastructure calls `flushBuffer` on the wrapped response, the call is
delegated to the actual response, which is committed. It's not possible
to alter the response (headers, content) anymore - the ETag filter can't
act.
This change prevents the `flushBuffer` call to be delegated and only
commits the underlying response once the cached content is copied to the
actual response stream.
Issue: SPR-13717