Commit Graph

10084 Commits

Author SHA1 Message Date
Brian Clozel f9ce11eef8 Provide controller level Cache-Control support
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
2015-03-23 18:05:14 +01:00
Brian Clozel 38f32e3816 Improve HTTP caching flexiblity
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
2015-03-23 18:01:04 +01:00
Markus Malkusch 953608ec49 Improve ETag & Last-Modifed support in WebRequest
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
2015-03-23 17:36:06 +01:00
Sam Brannen e086a637d5 Introduce BEFORE METHOD/CLASS modes in @DirtiesContext
Prior to this commit, @DirtiesContext could only be used to close a
test ApplicationContext after an entire test class or after a test
method; however, there are some use cases for which it would be
beneficial to close a test ApplicationContext before a given test class
or test method -- for example, if some rogue (i.e., yet to be
determined) test within a large test suite has corrupted the original
configuration for the ApplicationContext.

This commit provides a solution to such testing challenges by
introducing the following modes for @DirtiesContext.

 - MethodMode.BEFORE_METHOD: configured via the new methodMode attribute

 - ClassMode.BEFORE_CLASS and ClassMode.BEFORE_EACH_TEST_METHOD: both
   configured via the existing classMode attribute

Issue: SPR-12429
2015-03-22 21:33:20 +01:00
Sam Brannen 6028a64444 Polish Javadoc for TestContext 2015-03-22 21:33:06 +01:00
Stephane Nicoll 9172a6d05e Restore proper use of CacheLoader
Since Guava 11, CacheLoader is only invoked with a LoadingCache but the
GuavaCache wrapper is always invoking getIfPresent(), available on the
main Guava Cache interface.

Update GuavaCache#get to check for the presence of a LoadingCache and
call the appropriate method.

Issue: SPR-12842
2015-03-22 10:02:36 +01:00
Juergen Hoeller 7513bd5757 Latest dependency updates (Groovy 2.4.2, Hibernate Validator 5.2 beta 1) 2015-03-21 01:19:16 +01:00
Juergen Hoeller 56273a8ff3 Polishing 2015-03-21 01:19:01 +01:00
Sam Brannen 3d2bde7156 Add tests that use the new generate-name attribute
This commit updates the Spr8849Tests test suite to include XML
configuration that guarantees that a unique database name is always
automatically generated (via the new 'generate-name' attribute that was
introduced in SPR-8849) while reusing the same bean name (i.e.,
'dataSource').

Issue: SPR-8849
2015-03-21 00:39:54 +01:00
Sam Brannen c0fbe0ae5a Support unique names for embedded databases
Development teams often encounter errors with embedded databases if
their test suite inadvertently attempts to recreate additional
instances of the same database. This can happen quite easily if an XML
configuration file or @Configuration class is responsible for creating
an embedded database and the corresponding configuration is then reused
across multiple testing scenarios within the same test suite (i.e.,
within the same JVM process) -- for example, integration tests against
embedded databases whose ApplicationContext configuration only differs
with regard to which bean definition profiles are active.

The root cause of such errors is the fact that Spring's
EmbeddedDatabaseFactory (used internally by both the
<jdbc:embedded-database> XML namespace element and the
EmbeddedDatabaseBuilder for Java Config) will set the name of the
embedded database to "testdb" if not otherwise specified. For the case
of <jdbc:embedded-database>, the embedded database is typically
assigned a name equal to the bean's id. Thus, subsequent attempts to
create an embedded database will not result in a new database. Instead,
the same JDBC connection URL will be reused, and attempts to create a
new embedded database will actually point to an existing embedded
database created from the same configuration.

This commit addresses this common issue by introducing support for
generating unique names for embedded databases. This support can be
enabled via:

 - EmbeddedDatabaseFactory.setGenerateUniqueDatabaseName()

 - EmbeddedDatabaseBuilder.generateUniqueName()

 - <jdbc:embedded-database generate-name="true" ... >

Issue: SPR-8849
2015-03-21 00:21:59 +01:00
Rossen Stoyanchev 0c9cd4cc32 SubProtocolWebSocketHandler checks if session is open
Issue: SPR-12812
2015-03-20 17:45:27 -04:00
Rossen Stoyanchev 4886edd10b Send STOMP ERROR if external broker not available
Issue: SPR-12820
2015-03-20 17:34:31 -04:00
Rossen Stoyanchev 18039785ae Update Javadoc of AsyncHandlerInterceptor
Issue: SPR-12608, SPR-12720
2015-03-20 16:58:01 -04:00
Rossen Stoyanchev f06dffb714 Improve MockHttpServletRequest/Response charset parsing
Issue: SPR-12677
2015-03-20 16:12:46 -04:00
Rossen Stoyanchev a57d42829c Support {/var} syntax in UriComponentsBuilder
Issue: SPR-12750
2015-03-20 15:35:43 -04:00
Rossen Stoyanchev 6a96c26dd4 Add HttpRange tests, set Accept-Range header, polish
Issue: SPR-10805
2015-03-20 15:35:43 -04:00
Arjen Poutsma da48739628 Support byte ranges in ResourceHttpRequestHandler
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
2015-03-20 15:35:43 -04:00
Rossen Stoyanchev 0e7eecfe34 Add copyToUriComponentsBuilder method
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
2015-03-20 15:35:43 -04:00
Juergen Hoeller 8e4bfa9cc1 BeansDtdResolver resolves spring-beans.dtd declarations to spring-beans-2.0.dtd file
Issue: SPR-12836
2015-03-20 17:41:04 +01:00
Juergen Hoeller 898c24fcdd Optimized access to resolved bean type (avoiding BeanFactory locks)
Revised HandlerMethod.getBeanType() impl for both web and messaging.
In addition, HandlerMethods get created with the internal BeanFactory now.

Issue: SPR-12832
2015-03-20 17:35:44 +01:00
Sam Brannen ab771dfd97 Refactor tests to use the new database-name attribute
This commit refactors the XML configuration used by the tests in the
Spr8849Tests test suite so that a unique database name is always
generated (via the new 'database-name' attribute that was introduced in
SPR-12835) while reusing the same bean name (i.e., 'dataSource').

This is a much more robust alternative to the previous work-around
since the name of the DataSource does not randomly change across
application contexts, thus allowing proper autowiring by name and bean
referencing within XML configuration.

Issue: SPR-8849
2015-03-20 17:11:52 +01:00
Sam Brannen c36c6cbfaa Introduce database-name in <jdbc:embedded-database>
Prior to this commit, the EmbeddedDatabaseBeanDefinitionParser set the
name of the embedded database that it configured to the value of its
'id'. This made it impossible to assign unique names to embedded
databases if the same bean 'id' (e.g, 'dataSource') was used across
multiple application contexts loaded within the same JVM, which is
often the case within an integration test suite. In contrast, the
EmbeddedDatabaseBuilder already provides support for setting the name
in Java Config. Thus there is a disconnect between XML and Java
configuration.

This commit addresses this issue by introducing a 'database-name'
attribute in <jdbc:embedded-database />. This allows developers to set
unique names for embedded databases -- for example, via a SpEL
expression or a property placeholder that is influenced by the current
active bean definition profiles.

Issue: SPR-12835
2015-03-20 16:42:04 +01:00
Sam Brannen 7e2f12cf9f Allow <jdbc:embedded-database> to be declared w/o id
This commit modifies EmbeddedDatabaseBeanDefinitionParser so that the
<jdbc:embedded-database> XML namespace element can be declared as an
anonymous bean (i.e., without an explicit ID).

Issue: SPR-12834
2015-03-20 15:48:04 +01:00
Sam Brannen 85e4b24abb Introduce spring-jdbc-4.2.xsd
This commit introduces spring-jdbc-4.2.xsd in order to support upcoming
changes to the JDBC XML namespace.

In addition, this commit polishes the XSD documentation with regard to
use cases for script execution.
2015-03-20 15:31:41 +01:00
Rossen Stoyanchev 83ff0adc2e Add accessors for expirationTime in FlashMap
FlashMap now has a single field reflecting the expiration time and
also provides accessors that can be used for serialization purposes.

Issue: SPR-12757
2015-03-19 17:25:44 -04:00
Rossen Stoyanchev de9c9febc3 Compare encoded params in AbstractFlashMapManager
AbstractFlashMapManager no longer decodes the target query parameters
it needs to use to match to the request after the redirect.

Instead it stores query parameters as-is adn then relies on parsing the
encoded query string after the redirect.

Issue: SPR-12569
2015-03-19 16:57:26 -04:00
Rossen Stoyanchev 46537a76ed Polish FlashMapManagerTests 2015-03-19 15:04:13 -04:00
Rossen Stoyanchev 41e437066e Support @MessageExceptionHandler w/ @ControllerAdvice
This change adds support for global @MessageExceptionHandler methods
with STOMP over WebSocket messages. Such methods can be added to
@ControllerAdvice annotated components, much like @ExceptionHandler
methods for Spring MVC.

Issue: SPR-12696
2015-03-19 14:21:24 -04:00
Juergen Hoeller 192462902e Consistent support for Java 8 default methods (in interfaces implemented by user classes)
Covers ReflectionUtils.doWithMethods as well as affected annotation post-processors.
Includes an extension of MethodMetadata for the detection of @Bean default methods.

Issue: SPR-12822
Issue: SPR-10919
2015-03-19 16:50:15 +01:00
Juergen Hoeller 778a01943b ResolvableType-based type matching at the BeanFactory API level
Issue: SPR-12147
2015-03-18 23:05:13 +01:00
Juergen Hoeller a3e5fbf5ed Revised DefaultManagedAwareThreadFactory to make its non-JNDI fallback work
Issue: SPR-12830
2015-03-18 21:21:46 +01:00
Sam Brannen ce68c4dccb Polish Javadoc in MutablePersistenceUnitInfo
- Using Javadoc syntax for code formatting instead of JIRA's.
2015-03-17 23:10:56 +01:00
Juergen Hoeller 6f98cf3add Explicit documentation on 4.1+ properties in AbstractMessageListenerContainer 2015-03-17 21:41:37 +01:00
Juergen Hoeller 4f1d9fddc8 Explicit documentation on MutablePersistenceUnitInfo's addManagedPackage
Issue: SPR-12821
2015-03-17 21:28:19 +01:00
Juergen Hoeller 370e3a52bf HttpComponentsClientHttpRequestFactory supports plain HttpClient (i.e. non-CloseableHttpClient implementations) as well
Issue: SPR-12826
2015-03-17 21:24:51 +01:00
Sam Brannen 8ee0e98540 Ensure WebSocketStompClientTests compiles in Gradle build as well 2015-03-17 18:47:24 +01:00
Sam Brannen ffff596ae6 Polish GroovyBeanDefinitionReader ctr Javadoc 2015-03-17 18:19:17 +01:00
Sam Brannen 9930a8715f Clean up & suppress warnings in spring-messaging 2015-03-17 17:58:32 +01:00
Sam Brannen 03739c25d3 Ensure WebSocketStompClientTests compiles in STS 3.6.4 2015-03-17 17:46:46 +01:00
Sam Brannen bf0703e07e Delete unused imports in spring-messaging 2015-03-17 17:29:38 +01:00
Rossen Stoyanchev febcd0c46d Add baseUrl overloaded MvcUriComponentsBuilder methods
Issue: SPR-12800
2015-03-16 20:45:01 -04:00
Juergen Hoeller 7f9975e34d Latest dependency updates (Jetty 9.2.10, Netty 4.0.26, Undertow 1.1.3) 2015-03-16 21:21:24 +01:00
Juergen Hoeller 162ee36700 Polishing 2015-03-16 21:01:28 +01:00
Juergen Hoeller c43acd7675 SpringValidatorAdapter allows for fine-tuning the FieldError representation
Issue: SPR-12819
2015-03-16 21:01:18 +01:00
Juergen Hoeller 768f6e836a Bean class name may contain SpEL expression for late resolution
Issue: SPR-12817
2015-03-16 20:53:41 +01:00
Stephane Nicoll 66ec5ea2d1 Merge pull request #755 from bwestrich/master
* pull755:
  fix typo
2015-03-16 18:22:35 +01:00
Brian Westrich 27b57ec332 fix typo 2015-03-14 07:43:02 -05:00
Juergen Hoeller abd7052b16 ContentCachingRequestWrapper converts IOException to IllegalStateException
Issue: SPR-12810
(cherry picked from commit ce84faf)
2015-03-13 20:20:51 +01:00
Juergen Hoeller 6c169bd644 Initial support for JSR-354 Money & Currency
Issue: SPR-12209
2015-03-13 19:40:00 +01:00
Juergen Hoeller bc6a98c144 Polishing (in particular updating javadoc references to Apache Commons) 2015-03-13 18:19:10 +01:00