Before this change ResponseStatusExceptionResolver always used
.sendError despite the javadoc on @ResponseStatus#code. This was
perhaps justifiable from a HandlerExceptionResolver. Nevertheless
.setStatus should be more REST API friendly while still marking
the response as an error.
Issue: SPR-11193
Before this change the AbstractMessageConverterMethodProcessor always
raised a 406 if it couldn't find a converter. However if the reason
for not finding it is because there is simply no converter for the
return value type (i.e. programming error) and doesn't have anything to
do with content negotiation, then we should raise a 500 instead and
make it easier to figure out what's wrong.
Issue: SPR-13135
This commit improves SPR-13090 and avoids adding duplicate ETag and
Last-Modified headers in HTTP responses.
Previously, those were added twice to the response since:
* we're adding all ResponseEntity headers to the response
* the `checkNotModified` methods automatically add those headers
Issue: SPR-13090
Before this change HandlerMethodReturnValueHandler's were invoked in a
specific order (type-based, annotation-based, custom). However handlers
that deal with asynchronous return value handling need to always be
considered first. This affects custom handlers in particular since they
are normally ordered last.
This change introduces an AsyncHandlerMethodReturnValueHandler
sub-interface with a single method to determine if the return value is
asynchronous and if it is to look for a matching handler only among
those that are of type AsyncHandlerMethodReturnValueHandler.
Issue: SPR-13083
This commit introduces the following changes in AbstractHandlerExceptionResolver:
- warnLogger used to log exception is enabled by default
- the exception message is now logged instead of the whole exception stacktrace
- warn logging is only performed if doResolveException() returns a non-null
ModelAndView, in order to avoid logging multiple times the error
Issue: SPR-13100
Before this change a missing path variable value resulted in a 400
error where in fact the error is due to a mismatch between the
declared @PathVariable and the URI template, i.e. a 500 error.
This change introduced a MissingPathVariableException as a sub-class
of ServletRequestBindingException (the exception previously thrown)
and results in a response status code of 500 by default.
Issue: SPR-13121
In AnnotatedElementUtils, all methods pertaining to merging annotation
attributes have been renamed to "getMerged*()" and "findMerged*()"
accordingly. Existing methods such as getAnnotationAttributes(..) have
been deprecated in favor of the more descriptive "merged" variants.
This aligns the naming conventions in AnnotatedElementUtils with those
already present in AnnotationReadingVisitorUtils.
The use of "annotationType" as a variable name for the fully qualified
class name of an annotation type has been replaced with
"annotationName" in order to improve the readability and intent of the
code base.
In MetaAnnotationUtils.AnnotationDescriptor, getMergedAnnotation() has
been renamed to synthesizeAnnotation(), and the method is now
overridden in UntypedAnnotationDescriptor to always throw an
UnsupportedOperationException in order to avoid potential run-time
ClassCastExceptions.
Issue: SPR-11511
Prior to this change, the `"Last-Modified"` and "`Etag`" support had
been improved with SPR-11324: HTTP response headers are now
automatically added for conditional requests and more.
This commit fixes the format of the "`Last-Modified`" and "`ETag`"
values, which were using an epoch timestamp rather than an HTTP-date
format defined in RFC 7231 section 7.1.1.1.
Also, Conditional responses are only applied when the given response
applies, i.e. when it has an compatible HTTP status (2xx).
Issue: SPR-13090
This commit introduces the following changes:
- configureCors(CorsConfigurer configurer) is renamed to
addCorsMappings(CorsRegistry registry)
- enableCors(String... pathPatterns) is renamed to
addMapping(String pathPattern)
- <cors /> element must have at least one <mapping /> child
element in order to be consistent with XML based configuration
and have more explicit configuration
Issues: SPR-12933, SPR-13046
This commit introduces support for this kind of CORS XML namespace configuration:
<mvc:cors>
<mvc:mapping path="/api/**"
allowed-origins="http://domain1.com, http://domain2.com"
allowed-methods="GET, PUT"
allowed-headers="header1, header2, header3"
exposed-headers="header1, header2" allow-credentials="false"
max-age="123" />
<mvc:mapping path="/resources/**" allowed-origins="http://domain1.com" />
</mvc:cors>
Issue: SPR-13046
Spring Framework 4.2 RC1 introduced support for synthesizing an
annotation from an existing annotation in order to provide additional
functionality above and beyond that provided by Java. Specifically,
such synthesized annotations provide support for @AliasFor semantics.
As luck would have it, the same principle can be used to synthesize an
annotation from any map of attributes, and in particular, from an
instance of AnnotationAttributes.
The following highlight the major changes in this commit toward
achieving this goal.
- Introduced AnnotationAttributeExtractor abstraction and refactored
SynthesizedAnnotationInvocationHandler to delegate to an
AnnotationAttributeExtractor.
- Extracted code from SynthesizedAnnotationInvocationHandler into new
AbstractAliasAwareAnnotationAttributeExtractor and
DefaultAnnotationAttributeExtractor implementation classes.
- Introduced MapAnnotationAttributeExtractor for synthesizing an
annotation that is backed by a map or AnnotationAttributes instance.
- Introduced a variant of synthesizeAnnotation() in AnnotationUtils
that accepts a map.
- Introduced findAnnotation(*) methods in AnnotatedElementUtils that
synthesize merged AnnotationAttributes back into an annotation of the
target type.
The following classes have been refactored to use the new support for
synthesizing AnnotationAttributes back into an annotation.
- ApplicationListenerMethodAdapter
- TestAnnotationUtils
- AbstractTestContextBootstrapper
- ActiveProfilesUtils
- ContextLoaderUtils
- DefaultActiveProfilesResolver
- DirtiesContextTestExecutionListener
- TestPropertySourceAttributes
- TestPropertySourceUtils
- TransactionalTestExecutionListener
- MetaAnnotationUtils
- MvcUriComponentsBuilder
- RequestMappingHandlerMapping
In addition, this commit also includes changes to ensure that arrays
returned by synthesized annotations are properly cloned first.
Issue: SPR-13067
Reinstate a variant of the `WebContentGenerator.checkAndPrepare` method
for projects that are using it.
This variant is now marked as deprecated.
Issue: SPR-11792
Prior to this commit, the `ResourceHttpRequestHandler` would not
properly handle HTTP requests to **directories contained in JARs**.
This would result in HTTP 500 errors, caused by `FileNotFoundException`
or `NullPointerException`.
This can be tracked to webapp ClassLoader implementations in servlet
containers:
* in Jetty9x, fetching a directory within a JAR as a `Resource` and
getting its InputStream work fine, but attempting to `close()` it
results in a NullPointerException as the underlying stream is null.
* In Tomcat6x, one cannot fetch an InputStream for the same `Resource`
as it throws a FileNotFoundException.
This change adds more try/catch clauses and catches more Exception so as
to result in HTTP 200 OK responses instead of server errors. While this
is inconsistent because the same code path would result in HTTP 404 with
existing directories on the file system, there's no other simple way to
make those checks for resources contained in JARs.
Issue: SPR-12999
Prior to this commit, WebJars users needed to use versioned links within
templates for WebJars resources, such as `/jquery/1.2.0/jquery.js`.
This can be rather cumbersome when updating libraries - all references
in templates need to be updated.
One could use version-less links in templates, but needed to add a
specific MVC Handler that uses webjars.org's webjar-locator library.
While this approach makes maintaing templates easier, this makes HTTP
caching strategies less optimal.
This commit adds a new WebJarsResourceResolver that search for resources
located in WebJar locations. This ResourceResolver is automatically
registered if the "org.webjars:webjars-locator" dependency is present.
Registering WebJars resource handling can be done like this:
```java
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:META-INF/resources/webjars")
.resourceChain(true)
.addResolver(new WebJarsResourceResolver());
}
```
Issue: SPR-12323
polish
Prior to this commit, registering `HandlerInterceptor`s using the
`InterceptorRegistry` would not guarantee their order of execution. In
fact, `HandlerInterceptor`s would always be executed before
`MappedInterceptor`s.
This change makes `MappedInterceptor` implement the `HandlerInterceptor`
interface, in order to register all interceptors in a single ordered
list. The order of execution of interceptors is now guaranteed in the
`HandlerExecutionChain` built by `AbstractHandlerMapping`.
Issue: SPR-12673
MvcUriComponentsBuilder::fromMethodCall creates wrong URLs with derived
controller classes. The @RequestMapping of the declaring class of the
method that is called is used instead of the @RequstMapping of the
given controller class.
https://jira.spring.io/browse/SPR-13033
After this change CorsProcessor has a single processRequest method and
it also explicitly deals with a null CorsConfiguration, which for
pre-flight requests results in a rejection while for simple requests
results in no CORS headers added.
The AbstractHandlerMapping now uses a LinkedHashMap to preserve the
order in which global patterns are provided.
This commit adds JavaConfig based global CORS configuration
capabilities to Spring MVC. It is now possible to specify
multiple CORS configurations, each mapped on a path pattern,
by overriding
WebMvcConfigurerAdapter#configureCrossOrigin(CrossOriginConfigurer).
It is also possible to combine global and @CrossOrigin based
CORS configuration.
Issue: SPR-12933
Prior to this commit, the ResourceUrlEncodingFilter would fail with a
StringIndexOutOfBoundsException when:
* the current request has a servlet context
* the URL to encode is relative and is shorter than the context value
This change defensively checks for those lengths and delegates to the
parent implementation if necessary.
Issue: SPR-13018
Prior to this commit, AntPathMatcher would not correctly combine a path
that ends with a separator with a path that starts with a separator.
For example, `/foo/` + `/bar` combined into `/foo//bar`.
Specifically, this commit:
- Removes the duplicated separator in combined paths
- Improves RequestMappingInfo's toString() representation
- Fixes Javadoc formatting in AntPathMatcher
- Polishes AntPathMatcherTests
- Polishes Javadoc in AbstractRequestCondition
Issue: SPR-12975
Prior to this change, the `UrlTag` would simply append the remote
context and the path value in case of a context relative URL.
The following code snippet would output "//foo":
```
<spring:url value="/foo" context="/" />
```
This change now removes trailing slashes in remote context to avoid
this.
Issue: SPR-12782
- Methods which search for a specific annotation now properly ensure
that the sought annotation was actually found.
- Both the "get" and the "find" search algorithms no longer needlessly
traverse meta-annotation hierarchies twice.
- Both the "get" and the "find" search algorithms now properly
increment the metaDepth when recursively searching within the
meta-annotation hierarchy.
- Redesigned getMetaAnnotationTypes() so that it doesn't needlessly
search irrelevant annotations.
- Documented and tested hasMetaAnnotationTypes().
- Documented isAnnotated().
Issue: SPR-11514
Before this change AbstractHandlerMethodMapping used a map from Method
to CorsConfiguration. That works for regular @RequestMapping methods.
However frameworks like Spring Boot and Spring Integration may
programmatically register the same Method under multiple mappings,
i.e. adapter/gateway type classes.
This change ensures that CorsConfiguraiton is indexed by HandlerMethod
so that we can store CorsConfiguration for different handler instances
even when the method is the same.
In order for to make this work, HandlerMethod now provides an
additional field called resolvedFromHandlerMethod that returns the
original HandlerMethod (with the String bean name). This makes it
possible to perform reliable lookups.
Issue: SPR-11541
This commit introduces failing (but currently disabled) test cases in
HandlerMethodAnnotationDetectionTests that attempt to reproduce the
scenario described in SPR-9517.
See: ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass
Furthermore, this commit also introduces passing tests cases for a
similar scenario. See: ParameterizedSubclassOverridesDefaultMappings
Issue: SPR-9517
CorsConfiguration now provides methods to check and determine the
allowed origin, method, and headers according to its own configuration.
This simplifies significantly the work that needs to be done from
DefaultCorsProcessor. However an alternative CorsProcessor can still
access the raw CorsConfiguration and perform its own checks.
Issue: SPR-12885
This commit adds CORS related headers to HttpHeaders
and update DefaultCorsProcessor implementation to
use ServerHttpRequest and ServerHttpResponse instead
of HttpServletRequest and HttpServletResponse. Usage
of ServerHttpResponse allows to avoid using Servlet 3.0
specific methods in order keep CORS support Servlet 2.5
compliant.
Issue: SPR-12885
The change to provide public register/unregister methods in
AbstractHandlerMethodMapping assumed that a single method cannot be
mapped more than once. This is not the case with the MvcEndpoints and
EndpointHandlerMapping from Spring Boot which wrap one or more
non-web Endpoint types with an MvcEndpointAdapter in order to expose
them for use over the web. In effect Spring MVC sees a single handler
method mapped many times.
This change removes that assumption so rather than unregistering with
a HandlerMethod, which is not necessarily unique, the unregister method
now takes the actual mapping, which is the only thing that should actually
be unique.
Issue: SPR-11541
This commit adds additional context to the exception message generated
when two candidate methods are discovered in MvcUriComponentsBuilder's
getMethod(Class<?>, String, Object...).
Issue: SPR-12977
This commit introduces a new fromMethodNameWithBridgedMethod() test in
MvcUriComponentsBuilderTests which is currently disabled via @Ignore
until this bug is resolved.
Issue: SPR-12977
When used in combination with GzipResourceResolver, the
CachingResourceResolver does not properly cache results, since it only
takes the request path as a input for cache key generation.
Here's an example of that behavior:
1. an HTTP client requests a resource with `Accept-Encoding: gzip`, so
the GzipResourceResolver can resolve a gzipped resource.
2. the configured CachingResourceResolver caches that resource.
3. another HTTP client requests the same resource, but it does not
support gzip encoding; the previously cached gzipped resource is still
returned.
This commit uses the presence/absence of gzip encoding support as an
input in cache keys generation.
Issue: SPR-12982
Before this change AbstractHandlerMethodMapping contained multiple
maps all containing different kinds of mapping meta-data. After the
change a MappingDefinitionRegistry inner class encapsulates these
fields along with their initialization code.
Issue: SPR-11541
Before 4.2 the MvcUriComponentsBuilder exposed only static factory
methods and therefore there should be no reason for it to extend
UriComponentsBuilder (design oversight). It's also highly unlikely
for application code to treat MvcUriCB as UriCB since there is no
need and no way to obtain an instance (constructor is protected).
This change removes the base class declaration from MvcUriCB.
Issue: SPR-12617
Before this change MvcUriComponentsBuilder exposed only static factory
methods for creating links where the links are relative to the current
request or a baseUrl explicitly provided as an argument.
This change allows creating an MvcUriComponents builder instance with
a built-in baseUrl. The instance can then be used with non-static
withXxx(...) method alternatives to the static fromXxx(...) methods.
Issue: SPR-12617
This commit adds support for script based templating. Any templating
library running on top of a JSR-223 ScriptEngine that implements
Invocable like Nashorn or JRuby could be used.
For example, in order to render Mustache templates thanks to the Nashorn
Javascript engine provided with Java 8+, you should declare the following
configuration:
@Configuration
@EnableWebMvc
public class MustacheConfig extends WebMvcConfigurerAdapter {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.scriptTemplate();
}
@Bean
public ScriptTemplateConfigurer configurer() {
ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
configurer.setEngineName("nashorn");
configurer.setScripts("mustache.js");
configurer.setRenderObject("Mustache");
configurer.setRenderFunction("render");
return configurer;
}
}
The XML counterpart is:
<beans>
<mvc:annotation-driven />
<mvc:view-resolvers>
<mvc:script-template />
</mvc:view-resolvers>
<mvc:script-template-configurer engine-name="nashorn" render-object="Mustache" render-function="render">
<mvc:script location="mustache.js" />
</mvc:script-template-configurer>
</beans>
Tested with:
- Handlebars running on Nashorn
- Mustache running on Nashorn
- React running on Nashorn
- EJS running on Nashorn
- ERB running on JRuby
- String templates running on Jython
Issue: SPR-12266
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
The check for an empty request body InputStream is now in the base
class AbstractMessageConverterMethodArgumentResolver shared for
all arguments that involve reading with an HttpMessageConverter --
@RequestBody, @RequestPart, and HttpEntity.
When an empty body is detected any configured RequestBodyAdvice is
given a chance to select a default value or leave it as null.
Issue: SPR-12778, SPR-12860, SPR-12861
RequestBodyAdvice is analogous to ResponseBodyAdvice (added in 4.1)
but for intercepting for reading the request with an
HttpMessageConverter for resolving an @RequestBody or an HttpEntity
method argument.
Issue: SPR-12501
Introduces an AbstractXlsView and dedicated subclasses for POI's xmlx support.
Deprecates the traditional AbstractExcelView which is based on pre POI 3.5 API.
Issue: SPR-6898
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 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
Revised HandlerMethod.getBeanType() impl for both web and messaging.
In addition, HandlerMethods get created with the internal BeanFactory now.
Issue: SPR-12832
FlashMap now has a single field reflecting the expiration time and
also provides accessors that can be used for serialization purposes.
Issue: SPR-12757
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
This commit ensures that @NumberFormat can be used as a
meta-annotation, as was already the case for @DateTimeFormat.
In addition, this commit polishes FormattingConversionServiceTests and
MvcNamespaceTests.
Issue: SPR-12743
Prior to this change, location checks for serving resources would append
`/` to the location path it didn't already have one.
This commit makes sure not to append a `/` if the provided location is
actually a file.
Issue: SPR-12747
Before this change, detection of X-Forwarded-* headers was only built
into ServletUriComponentsBuilder.
This change adds a new method for creating a UriComponentsBuilder from
an existing HttpRequest. This is equivalent to the fromUri method +
X-Forwarded-* header values.
Prior to this change, the `ResourceUrlProvider.getForLookupPath` method
would try to match handlers using the keySet order in the
handlerMappings Map. In case of several matches, the handler used for
the return value could vary, since the registration order in the
handlerMappings can't be guaranteed in the configuration.
This commit now collects all matching handlers and sort them using a
`PatternComparator`, in order to try each handler from the most specific
mapping to the least.
Issue: SPR-12647
This commit adds ResponseBodyEmitter and SseEmitter (and also
ResponseEntity<ResponseBodyEmitter> and ResponseEntity<SseEmitter>) as
new return value types supported on @RequestMapping controller methods.
See Javadoc on respective types for more details.
Issue: SPR-12212
Prior to this change, the ResourceUrlProvider would listen to
ContextRefreshedEvents and autodetect resource handlers each time. This
can cause issues when multiple contexts are involved and the last one
has no resource handler, thus clearing the previously detected ones.
This commit disables resource handlers auto-detection once some have
been detected with a refreshed context.
Issue: SPR-12592
Prior to this change, location paths used for resource handling would
not allow "non-cleaned, relative paths" such as
`file://home/user/static/../static/`. When checking if the resolved
resource's path starts with the location path, a mismatch would happen
when comparing for example:
* the location `file://home/user/static/../static/`
* and the resource `file://home/user/static/resource.txt`
This commit cleans the location path before comparing it to the resource
path.
Issue: SPR-12624
This commit allows the use of "protcol relative URLs" (i.e. URLs without
scheme, starting with `//`), often used to serve resources automatically
from https or http with third party domains.
This syntax is allowed by RFC 3986.
Issue: SPR-12632
This commit fixes the default value for the contextRelative attribute of
a RedirectView, when this view is registered via a
RedirectViewController in XML. The value is set to true.
Note that the default value for this is correctly documented in
spring-mvc-4.1.xsd. Also, the documentation and implementation for its
javadoc counterpart also enforces true as a default value.
Issue: SPR-12607
This commit introduces the SpringHandlerInstantiator
class, a Jackson HandlerInstantiator that allows to autowire
Jackson handlers (JsonSerializer, JsonDeserializer, KeyDeserializer,
TypeResolverBuilder and TypeIdResolver) if needed.
SpringHandlerInstantiator is automatically used with
@EnableWebMvc and <mvc:annotation-driven />.
Issue: SPR-10768
Prior to this change, the ResourceUrlEncodingFilter would work well when
the application is mapped to "/". But when mapped to a non-empty servlet
context, this filter would not properly encode URLs and apply
ResourceResolver URL resolution for resources.
This commit makes sure that the lookup path is properly resolved in the
request URI, taking into account the servlet context.
Issue: SPR-12459
SPR-12354 applied new checks to make sure that served static resources
are under authorized locations.
Prior to this change, serving static resources from Servlet 3 locations
such as "/webjars/" would not work since those locations can be within
one of the JARs on path. In that case, the checkLocation method would
return false and disallow serving that static resource.
This change fixes this issue by making sure to call the
`ServletContextResource.getPath()` method for servlet context resources.
Note that there's a known workaround for this issue, which is using a
classpath scheme as location, such as:
"classpath:/META-INF/resources/webjars/" instead of "/webjars".
Issue: SPR-12432
- remove leading '/' and control chars
- improve url and relative path checks
- account for URL encoding
- add isResourceUnderLocation final verification
Issue: SPR-12354
With SPR-9293, it is now possible to HTML escape text while taking into
account the current response encoding. When using UTF-* encodings, only
XML markup significant characters are escaped, since UTF-* natively
support those characters.
This commit adds a new servlet context parameter to enable this fix by
default in a Spring MVC application:
<context-param>
<param-name>responseEncodedHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
Issue: SPR-12350, SPR-12132
During the HTTP Content Negotiation phase, the ContentNegotiationManager
uses configured ContentNegotiationStrategy(ies) to define the list of
content types accepted by the client.
When HTTP clients don't send Accept headers, nor use a configured
file extension in the request, nor a request param, developers can
define a default content type using the
ContentNegotiationConfigurer.defaultContentType() method.
This change adds a new overloaded defaultContentType method that takes a
ContentNegotiationStrategy as an argument. This strategy will take the
current request as an argument and return a default content type.
Issue: SPR-12286
This fix addresses a 4.1.1 regression where a raw ResponseEntity return
value (used to return potentially a different kind of body) caused an
exception.
The regression came from the fact we now try to render a null body in
order to give ResponseBodyAdvice a chance to substitute a different
value. That in turn means we have to try to determine the body type
from the method signature.
This change improves the logic for extracting the generic parameter
type to accommodate a raw ResponseEntity class. Also we avoid raising
HttpMediaTypeNotAcceptableException if the value to be rendered is
null.
Issue: SPR-12287
Commit https://github.com/spring-projects/spring-framework/commit/2b97d6
introduced a change where the path within the DispatcherServlet is
determined with each call to ResourceUrlProvider.getForRequestUrl.
To avoid repeating that every time a URL is encoded through the
response, we now cache the result of the lookupPath determination in
ResourceUrlEncodingFilter.
Issue: SPR-12332
The use of the HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE
in ResourceUrlProvider (as a way of saving lookup path determination)
leads to incorrect results. For example when the request is forwarded
the current requestUri may no longer be compariable to the value of the
PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE. Also where the request is mapped
using a pattern, the value of PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE is
not the same as the lookup path.
This change removes the use of the attribute from ResourceUrlProvider
and instead always determines the lookup path when getForRequestUrl
is called.
Issue: SPR-12332
Before this change, the type of asynchronously produced return values
(e.g. Callable, DeferredResult, ListenableFuture) could not be
properly determined with an actual resulting value of null. Or even
with an actual value returned, the generic type could not be properly
determined. This change fixes both of those issues.
Issue: SPR-12287
The getForRequestUrl method of ResourceUrlProvider uses the
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE attribute to
determine the relevant portion of the resource URL path.
However there are cases when that attribute may not have a leading
(e.g. when the current URL was matched to a prefix-based pattern
and hence extracted via PathMatcher#extractPathWithinPattern), which
interferes with the matching of resource URL paths to patterns.
This change ensures a leading slash is present
Issue: SPR-12281
The resourceHandlerMapping in the MVC Java config is not configured
with any interceptors, and in particular those added through the
InterceptorRegistry, which are otherwise added to all other handler
mapping beans created by the config. This means that the
ResourceUrlProviderExposingInterceptor (added in 4.0) is also not
used for resource requests.
This change ensures the ResourceUrlProviderExposingInterceptor is
configured on the resourceHandlerMapping.
Issue: SPR-12279
Jackson2ObjectMapperBuilder now allows to create ObjectMapper and XmlMapper
instances easily thanks to its fluent API.
This builder is used in Jackson message converters and views to instantiate default
ObjectMapper and XmlMapper.
This commit also add a createXmlMapper property to
Jackson2ObjectMapperFactoryBean in order to allow to create easily a XmlMapper
instance.
Issue: SPR-12243
When not ViewResolver's have been registered, detect if the context
contains any other ViewResolver beans. If not, add InternalResourceVR
to match default DispatcherServlet behavior.
Issue: SPR-12267
This change defers determination of whether to invoke a message
converter in case of a null @ResponseBody value (or ResponseEntity with
a null body) until after the invocation of the ResponseBodyAdvice
chain. This allows a ResponseBodyAdvice to handle null values
potentially turning them into non-null value.s
Issue: SPR-12152
Prior to this change, getForRequestUrl implementation would only work
for applications with a non-empty servlet path. So web applications
mapped to "/" would trigger a IllegalStateException while checking the
current request against the request path within the current mapping.
This change relaxes this and only check that the path within mapping is
within the request URL.
Issue: SPR-12158
This change moves the resource-cache configuration to the
<resource-chain/> tag, since enabling/disabling resource cache should
be driven by a property or a SpEL expression.
So now that configuration can be set with XML attributes:
<mvc:resource-chain resource-cache="true"
cache-manager="resourceCache" cache-name="test-resource-cache">
In order to mirror the JavaConfig behavior, the "resource-cache"
attribute is required.
Issue: SPR-12129
Before this change ResourceUrlProvider used getUrlMap to detect
ResourceHttpRequestHandler instances, however the map may contain bean
names as is the case when using <mvc:resources>. Instead it now uses
getHandlerMap.
This change adds a ResourceUrlProvider bean to the
ResourceBeanDefinitionParser to match the same in the Java config.
For consistency the name of the bean in the Java config is renamed.
Also a ResourceUrlProviderExposingInterceptor is declares as a global
MappedInterceptor.
Prior to this change, ResourceTransformers that transformed resources by
updating the links to other resources, worked only if links were
relative to the resource being transformed.
For example, when the CssLinkResourceTransformer rewrote links within
a "main.css" resource, only links such as "../css/other.css" were
rewritten.
Using relative links is a recommended approach, because it's totally
independent from the application servlet path, context path, mappings...
This change allows absolute links to be rewritten by those Transformers,
provided those links are accurate and point to existing resources.
Issue: SPR-12137
This commit changes the way a <mvc:resource-cache> can be configured
with a user defined Cache instance.
Now a reference to a CacheManager Bean and a Cache name must be
provided. This is a more flexible configuration for typical XML setups.
<mvc:resource-cache
cache-manager="resourceCache"
cache-name="test-resource-cache"/>
Issue: SPR-12129
With the new ResourceResolver abstraction and resource resolver chain
in 4.1, the assumption that resources are found by checking for the URL
path under the configured locations is no longer accurate.
A custom ResourceResolver could find resources in ways that don't
depend on a list of locations.
Issuse: SPR-12133
This change introduces a new <mvc:resource-chain/> tag that mirrors
the ResourceChainRegistration java config counterpart.
Resolvers and Transformers can be registered with bean/ref tags, and
specific tags have been created for <mvc:version-resovlver> and
<mvc:resource-cache> in order to make common configurations easier.
Note that a specific "auto-configuration" attribute on the
resource-chain allows to completely disable default registration of
Resolvers and Transformers (sane defaults considered by the Framework).
<mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/">
<mvc:resource-chain>
<mvc:resource-cache cache="resourceCache"/>
<mvc:resolvers>
<mvc:version-resolver>
<mvc:fixed-version-strategy version="abc" patterns="/**/*.js"/>
<mvc:content-version-strategy patterns="/**"/>
</mvc:version-resolver>
</mvc:resolvers>
<mvc:transformers>
<bean class="org.springframework.web.servlet.resource.AppCacheManifestTransformer"/>
</mvc:transformers>
</mvc:resource-chain>
</mvc:resources>
This also fixes a typo in the class name of
AppCacheManifestResourceTransfo*r*mer.
Issue: SPR-12129
This change separates out resource chain related methods previously in
ResourceHandlerRegistration into a new class ResourceChainRegistration
with the goal of improving readability.
Along with that, the registration of caching resolver and transformer
is now explicitly controled with a boolean flag (on the method used
to obtain the ResourceChainRegistration) and an overloaded method
also allows providing a Cache instance.
Issue: SPR-12124
This change moves the VersionStrategy builder-style methods from
ResourceHandlerRegistration to VersionResourceResolver.
This makes the methods more universally usable and also makes use of
ResourceHandlerRegistration more readable, i.e. simply a sequence of
addResource and addTransformer calls.
The ResourceHandlerRegistration now checks if the last resolver is an
instance of PathResourceResolver and if so it skips adding it.
This change also creates and adds the VersionResourceResolver (as well
as CssLinkTransformer) the first time any VersionStrategy is
registered. This ensures that custom resolvers (including an extension
of PathResourceResolver) may be added both before and after the
VersionResourceResolver.
Lastly this change renames addVersion and addVersionHash to be
consistent with addVersionStrategy.
Issue: SPR-12124
This change enables the ability to configure
ViewNameMethodReturnValueHandler & ModelAndViewMethodReturnValueHandler
with patterns to use to test for a custom redirect view name.
Issue: SPR-12054
This commit adds support for XML serialization/deserialization based on
the jackson-dataformat-xml extension. When using @EnableWebMvc or
<mvc:annotation-driven/>, Jackson will be used by default instead of JAXB2
if jackson-dataformat-xml classes are found in the classpath.
This commit introduces MappingJackson2XmlHttpMessageConverter and
MappingJackson2XmlView classes, and common parts between JSON
and XML processing have been moved to AbstractJackson2HttpMessageConverter
and AbstractJackson2View classes.
MappingJackson2XmlView supports serialization of a single object. If the model
contains multiple entries, MappingJackson2XmlView.setModelKey() should be
used to specify the entry to serialize.
Pretty print works in XML, but tests are not included since a Woodstox dependency
is needed, and it is better to continue testing spring-web and spring-webmvc
against JAXB2.
Issue: SPR-11785
Replace references to the old RFC 2616 (HTTP 1.1) with references
to the new RFCs 7230 to 7235.
This commit also deprecates:
- HttpStatus.USE_PROXY
- HttpStatus.REQUEST_ENTITY_TOO_LARGE in favor of HttpStatus.PAYLOAD_TOO_LARGE
- HttpStatus.REQUEST_URI_TOO_LONG in favor of HttpStatus.URI_TOO_LONG
Issue: SPR-12067
This change adds new methods in the ResourceHandlerRegistration API
for registering ResourceResolvers and ResourceTransformers, allowing
to better handle server-side resources in web applications.i
Here is an example of configuration for an HTML5 web application
that uses JavaScript and HTML5 appcache manifests:
registry.addResourceHandler("/**")
.addResourceLocations("classpath:static/")
.addTransformer(new AppCacheManifestTransfomer())
.addVersion("v1", "/**/*.js")
.addVersionHash("/**");
Issue: SPR-11982
Before this change if Velocity Spring form macro was bound to a path
which contains square brackets, those brackets would also appear in id
of generated tag, making the id invalid.
As of this fix all Velocity Spring form macros generate tag with id
that does not contain square brackets.
Issue: SPR-5172
This change adds support for configuring redirect view controllers and
also status controllers to the MVC Java config and the MVC namespace.
Issue: SPR-11543
This change makes it possible to configure RedirectView such that the
query string of the current request is added to the target URL.
This change is preparation for SPR-11543.
This change two new capabilities to ParameterizableViewController:
- configure a View instance (in addition to view name)
- configure response status code
The status code may be useful to send a 404 while also writing to the
body using a view.
The status code may also be used to override the redirect status code
of RedirectView. Even today it's possible to configure a "redirect:"
prefixed view name but the status code could not be selected. When a
3xx status is set, the code is passed on to the RedirectView while the
view name is automatically prefixed with "redirect:" (if not already).
For full control over RedirectView it is now also possible to
parameterize the controller with a View instance.
As one more possible resulting variation, given status 204 and no view
the request is considered handled (controller returns null).
This change is preparation for SPR-11543.
Since the MVC Java config always registers a ViewResolver (composite)
bean, at a very minimum we must add an InternalResourceViewResolver
consistent with default DispatcherServlet configuration and by
extension with the MVC namespace which falls back on DispatcherServlet
implicity if no <view-resolvers> element is present.
Issue: SPR-7093
After some further discussion:
The MVC config simplifies ViewResolver configuration especially where
content negotiation view resolution is involved.
The configuration of the underlying view technology however is kept
completely separate. In the case of the MVC namespace, dedicated
top-level freemarker, velocity, and tiles namespace elements are
provided. In the case of the MVC Java config, applications simply
declare FreeMarkerConfigurer, VelocityConfigurer, or TilesConfigurer
beans respectively.
Issue: SPR-7093
Following the separation of FreeMarker/Velocity/TilesConfigurer-related
configuration via separate interface, simplify and streamline the
view registration helper classes which no longer have much difference
(most are UrlBasedViewResolver's).
Updates to Javadoc and tests.
Issue: SPR-7093
This change improves the support for auto-registration of FreeMarker,
Velocity, and Tiles configuration.
The configuration is now conditional not only based on the classpath
but also based on whether a FreeMarkerConfigurer for example is already
present in the configuration.
This change also introduces FreeMarker~, Velocity~, and
TilesWebMvcConfigurer interfaces for customizing each view technology.
The WebMvcConfigurer can still be used to configure all view resolvers
centrally (including FreeMarker, Velocity, and Tiles) without some
default conifguration, i.e. without the need to use the new
~WebMvcConfigurer interfaces until customizations are required.
Issue: SPR-7093
This commit improves and completes the initial MVC namespace
view resolution implementation. ContentNegotiatingViewResolver
registration is now also supported.
Java Config view resolution support has been added.
FreeMarker, Velocity and Tiles view configurers are registered
depending on the classpath thanks to an ImportSelector.
For both, a default configuration is provided and documented.
Issue: SPR-7093
Move spring-webmvc-tiles3 content to spring-webmvc, and
create a spring-webmvc-tiles2 module with Tiles 2 support.
Its allows View Resolution to configure Tiles 3 instead of Tiles 2.
Issue: SPR-7093
When using ServletUriComponentsBuilder.fromRequest, this change
makes sure that:
* the default port is used when the "X-Forwarded-Host" header is set
and no port is defined in that header value
* to use the scheme defined in the "X-Forwarded-Proto" header if set
Issue: SPR-11872
This change renames AppCacheResourceTransformer to
AppCacheManifestTransfomer, in order to avoid confusion between this
transformer and the CacheResourceTransformer (which caches
transformations done by the chain to save CPU/memory at runtime).
Issue: SPR-11964
This change adds a new ResourceTransformer that helps handling resources
within HTML5 AppCache manifests for HTML5 offline application.
This transformer:
* modifies links to match the public URL paths
* appends a comment in the manifest, containing a Hash (e.g. "# Hash:
9de0f09ed7caf84e885f1f0f11c7e326")
See http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#offline
for more details on HTML5 offline apps and appcache manifests.
Here is a WebConfig example:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
AppCacheResourceTransformer appCacheTransformer =
new AppCacheResourceTransformer();
registry.addResourceHandler("/**")
.addResourceLocations("classpath:static/")
.setResourceResolvers(...)
.setResourceTransformers(..., appCacheTransformer);
}
Issue: SPR-11964
Users can not mix and match between "inner bean" argument resolver and "external bean" argument resolver. This commit only focuses only on argument-resolver, while the support could be extended to return value handlers as well.
Issue: SPR-11927
This change adds support for configuring ResourceResolvers and
ResourceTransformers with ResourceHttpRequestHandlers.
This is an example configuration:
<mvc:resources mapping="/resources/**" location="/">
<mvc:resolvers>
<bean class="org.springframework.web.servlet.resource.PathResourceResolver"/>
<ref bean="myResourceResolver"/>
</mvc:resolvers>
<mvc:transformers>
<bean class="org.springframework.web.servlet.resource.CssLinkResourceTransformer" />
</mvc:transformers>
</mvc:resources>
<bean id="myResourceResolver" class="org.example.resource.MyResourceResolver"/>
Issue: SPR-10951
This change exposes exceptions handled in the DispatcherServlet with a
HandlerExceptionResolver as a request attribute. This is done only when
the resolver returns an empty ModelAndView indicating the exception was
resolved but not view is required (e.g. status code was set). In such
cases the exception may be useful to any handlers in an ERRPR dispatch
by the servlet container.
Issue: SPR-11686
This commit introduces the RequestEntity, a class similar to
ResponseEntity, but meant for HTTP requests rather than responses. The
RequestEntity can be used both in RestTemplate as well as @MVC
scenarios.
The class also comes with a builder, similar to the one found in
ResponseEntity, which allows for building of a RequestEntity through a
fluent API.
Issue: SPR-11752
Prior to this commit, one of the available strategies for resolving
resources was the PrefixResourceResolver. Reconsidering the core goal of
this resolver and the FingerprintResourceResolver, we found that the
true core feature is versioning static resources application-wide.
This commit refactors both Resolvers by:
* having only on VersionResourceResolver
* that resolver takes a mapping of paths -> VersionStrategy
* provided VersionStrategy implementations are ContentBasedVS
(previously FingerprintRR), FixedVS (previously PrefixRR)
One can add a VersionResourceResolver like this:
Map<String, VersionStrategy> versionStrategies = new HashMap<>();
versionStrategies.put("/**/*.js", new PrefixVersionStrategy("prefix"));
versionStrategies.put("/**", new ContentBasedVersionStrategy());
VersionResourceResolver versionResolver = new VersionResourceResolver();
versionResolver.setVersionStrategyMap(versionStrategies);
List<ResourceResolver> resolvers = new ArrayList<ResourceResolver>();
resolvers.add(versionResolver);
resolvers.add(new PathResourceResolver());
Issue: SPR-11871
After this change, java.util.Optional is supported with @RequestParam,
@RequestHeader, and @MatrixVariable arguments in Java 8. When Optional
is used the required flag is effectively ignored.
Issue: SPR-11829
Prior to this commit, the CssLinkResourceTransformer would transform
"external resources", i.e. resources not served by the web application.
This commit only allows transformation for resources which path don't
contain scheme such as "file://" or "http://". Only relative and
absolute paths for resources served by the webapp are valid.
Issue: SPR-11860
Since SPR-11486 and SPR-10163, Path Matching options can be configured
to customize path matching options for RequestMappingHandlerMapping.
Prior to this commit, the defined pathMatcher and pathHelper instances
were only used in RequestMappingHandlerMapping.
This commit now registers pathMatcher and pathHelper beans under
well-known names and share them with several HandlerMappings beans,
such as ViewControllerMappings and ResourcesMappings.
Issue: SPR-11753
This commit adds a new function to the Spring tag library for preparing
links to @Controller methods. For more details see the Javadoc of
MvcUriComponentsBuilder.fromMappingName.
Issue: SPR-5779
This commit adds support for Groovy Markup templates.
Spring's support requires Groovy 2.3.1+.
To use it, simply create a GroovyMarkupConfigurer and a
GroovyMarkupViewResolver beans in the web application context.
Issue: SPR-11789
Enable JSONP support by wrapping the JSON output into
a callback when a JSONP query parameter specifying the
function name to use as callback is detected.
Default query parameter names recognized as JSONP ones
are "jsonp" and "callback". This list can be customized if
needed.
This commit also fixes JSONView support by removing
the view name specified in the model from the output.
Issue: SPR-8346
This change adds a ResourceTransformer that can be invoked in a chain
after resource resolution. The CssLinkResourceTransformer modifies a
CSS file being served in order to update its @import and url() links
(e.g. to images or other CSS files) to match the resource resolution
strategy (e.g. adding MD5 content-based hashes).
Issue: SPR-11800
The newly added support for ResponseBodyInterceptor is a good fit for
the (also recently added) support for the Jackson @JsonView annotation.
This change refactors the original implementation of @JsonView support
for @ResponseBody and ResponseEntity controller methods this time
implemented as an ResponseBodyInterceptor.
Issue: SPR-7156
This change introduces a new ResponseBodyInterceptor interface that can
be used to modify the response after @ResponseBody or ResponseEntity
methods but before the body is actually written to the response with the
selected HttpMessageConverter.
The RequestMappingHandlerAdapter and ExceptionHandlerExceptionResolver
each have a property to configure such interceptors. In addition both
RequestMappingHandlerAdapter and ExceptionHandlerExceptionResolver
detect if any @ControllerAdvice bean implements ResponseBodyInterceptor
and use it accordingly.
Issue: SPR-10859
This feature required support for response exposure on Servlet/PortletRequestAttributes, instead of just in the Servlet/PortletWebRequest subclasses.
Issue: SPR-11795
Spring MVC now supports Jackon's serialization views for rendering
different subsets of the same POJO from different controller
methods (e.g. detailed page vs summary view).
Issue: SPR-7156
Before this change UrlTag expanded URI vars and encoded them using
UriUtils.encodePath.
This change makes it possible to expand using
UriUtils.encodePathSegment, which means a "/" is encoded as "%2F".
To expand with path segment semantics, prefix the URI var name "/":
<spring:url value="/url/path/{/var}">
<spring:param name="var" value="my/Id" />
</spring:url>
Issue: SPR-11401
This change adds a strategy for assigning a default name to an
@RequestMapping controller method. The @RequestMapping annotation
itself now has a name attribute allowing the explicit assignment
of a mapping name.
This is mainly intended for use in EL expressions in views. The
RequestContext class now provides a getMvcUrl method that internally
delegates to MvcUriComponents to look up the handler method.
See the Javadoc of MvcUriComponents.fromMappingName.
Issue: SPR-5779
This change refines the logic of "mapping" content negotiation
strategies with regards to how to handle cases where no mapping is
found.
The request parameter strategy now treats request parameter values that
do not match any mapped media type as 406 errors.
The path extension strategy provides a new flag called
"ignoreUnknownExtensions" (true by default) that when set to false also
results in a 406. The same flag is also exposed through the
ContentNegotiationManagerFactoryBean and the MVC Java config.
Issue: SPR-10170
Animal sniffer provides tools to assist verifying that classes
compiled with a newer JDK are compatible with an older JDK.
This integratesthe latest version of the tool (1.11) that
permits the use of custom annotations. Added @UsesJava7,
@UsesJava8 and @UsesSunHttpServer and annotated the few places
where we rely on a specific environment.
The verification process can be invoked by running the 'sniff'
task.
Issue: SPR-11604
polishing