Prior to this commit, the Spring MVC Test framework only provided
support for printing debug information about the MvcResult to STDOUT.
This commit introduces support for logging `MvcResult` details at
`DEBUG` level via the Apache Commons Logging API. In addition, this
commit introduces additional `print(..)` variants for printing debug
information to custom output streams and writers.
Specifically, `MockMvcResultHandlers` has been augmented with the
following new static methods:
- `log()`
- `print(OutputStream)`
- `print(Writer)`
Issue: SPR-13171
Prior to this commit, when rendering cookies via `andDo(print())` in
Spring MVC Test, the output for the `MockHttpServletResponse` would
look something like the following:
Cookies = [javax.servlet.http.Cookie@25084a1e]
The reason is that the Cookie class in javax.servlet-api-3.0.1.jar does
not implement toString(). Consequently, nothing about the cookie's
name, value, etc., is displayed, thereby making the debug output for
cookies next to useless.
This commit improves on this by implementing custom toString() logic
for cookies in debug output in Spring MVC Test. For example, the output
now looks like this (without the newlines):
Cookies = [[Cookie@47faa49c name = 'enigma', value = '42', \\
comment = [null], domain = [null], maxAge = -1, \\
path = [null], secure = false, version = 0, \\
httpOnly = false]]
In addition, this commit fixes a minor bug for FlashMap debug output if
the FlashMap is empty.
Issue: SPR-13168
Add a section on Groovy Markup Template support and
reorder sections in the View Technologies chapter, to have in order:
* Thymeleaf
* Groovy Markup Template
* Velocity and Freemarker
* JSPs
* Script Templates
* other views...
Issue: SPR-12829
This commit introduces the following changes:
- In AbstractMessageConverterMethodProcessor, the type aware variant of
canWrite() is now called when the converter implements
GenericHttpMessageConverter.
- The Javadoc has been updated in GenericHttpMessageConverter to make it clear
that the type aware canRead() and canWrite() methods should perform the same
checks than non type aware ones.
- AbstractGenericHttpMessageConverter now implements default type aware
canRead() and canWrite() methods than just call the non type aware variants.
Due to this, if subclasses just override the non type aware variants,
they still have the right behavior.
Issue: SPR-13161
Recent builds of Jetty 9.3 require that Jetty's own ServletContext
implementation be supplied to WebSocketServerFactory's init() method.
Otherwise, the Jetty server will fail to start with the exception
message: "Not running on Jetty, WebSocket support unavailable".
This commit refactors AbstractWebSocketIntegrationTests,
AbstractSockJsIntegrationTests, and all WebSocketTestServer
implementations in order to support this new requirement.
Specifically:
- WebSocketTestServer defines a new getServletContext() method;
TomcatWebSocketTestServer, UndertowTestServer, and
JettyWebSocketTestServer have all been updated to return the
ServletContext created by the embedded server.
- The setup() methods in AbstractWebSocketIntegrationTests and
AbstractSockJsIntegrationTests have been updated so that the
WebApplicationContext is supplied the appropriate ServletContext,
after deployConfig() has been invoked on the WebSocketTestServer but
before the WebApplicationContext is refreshed.
Issue: SPR-13162
The JettySockJsIntegrationTests are enabled in the performance build
only. Following the upgrade to Jetty 9.3 where the
JettyRequestUpgradeStrategy is now Lifecycle as wel as
ServletContextAware, we need to make sure the ApplicationContext
refresh occurs after the ServletContext has been set. This change
removes the explicit .refresh() call in the test setup and instead
relies on the DispatcherServlet to do that, which ensures that the
ServletContext with which it is initialized by Jetty has been set
on the ApplicationContext before that.
Prior to this commit, Spring's MimeType checked for equality between
two MIME types based on the equality of their properties maps; however,
the properties maps contain string representations of the "charset"
values. Thus, "UTF-8" is never equal to "utf-8" which breaks the
contract for character set names which must be compared in a
case-insensitive manner.
This commit addresses this issue by ensuring that "charset" properties
in MimeType instances are compared as Java Charset instances, thereby
ignoring case when checking for equality between charset names.
Issue: SPR-13157
Prior to this commit, it was only possible to declare SQL statements
via @Sql within external script resources (i.e., classpath or file
system resources); however, many developers have inquired about the
ability to inline SQL statements with @Sql analogous to the support for
inlined properties in @TestPropertySource.
This commit introduces support for declaring _inlined SQL statements_
in `@Sql` via a new `statements` attribute. Inlined statements are
executed after statements in scripts.
Issue: SPR-13159
After this change JettyRequestUpgradeStrategy implements Lifecyle,
which is used to init and cleanup the Jetty WebSocketServerFactory.
Since a RequestUpgradeStrategy is typically created reflectively
within DefaultHandshakeHandler, the Lifecycle events are propagated
from the top, i.e. the Spring MVC HandlerMapping through the
WebSocket/SockJsHttpRequestHandler.
Issue: SPR-13140
This commit adds canWrite() and write() methods to the
GenericHttpMessageConverter interface. These are type aware variants
of the methods available in HttpMessageConverter, in order to keep
parametrized type information when serializing objects.
AbstractMessageConverterMethodProcessor now calls those type aware
methods when the message converter implements GenericHttpMessageConverter.
AbstractJackson2HttpMessageConverter and GsonHttpMessageConverter uses
these new methods to make @ResponseBody method return type available
for type resolution instead of just letting the JSON serializer trying
to guess the type to use from the object to serialize.
Issue: SPR-12811
Previously, a method could only declare one Jms endpoint so if several
destinations share the exact same business logic, you'd still need one
separate method declaration per destination.
We now make sure that JmsListener is a repeatable annotation, introducing
JmsListeners for pre Java8 use cases.
Issue: SPR-13147
This change fixes a NullPointerException in GzipResourceResolver, which
assumed that calls to the `resolveResource` method were made with only
non-null values for request.
This is not the case for the VersionResourceResolver, which tries to
resolve resources that aren't requested per se by the HTTP request.
Issue: SPR-13149
This commit introduces a convenience method in AnnotationUtils for
synthesizing an annotation from its default attribute values.
TransactionalTestExecutionListener has been refactored to invoke this
new convenience method.
Issue: SPR-13087
This commit introduces support for automatically resolving a container
annotation configured via @Repeatable in AnnotationUtils'
getRepeatableAnnotations() and getDeclaredRepeatableAnnotations()
methods.
Issue: SPR-13068
This commit introduces a minor bug fix for getRepeatableAnnotations()
so that it fully complies with the contract of Java's
getAnnotationsByType() method with regard to repeatable annotations
declared on multiple superclasses.
Issue: SPR-13068
- Simplified "check" algorithms in CorsConfiguration
- Improved robustness of setter methods in CorsConfiguration in order to
avoid attempts to modify immutable lists
- Improved CORS documentation and fixed typo
- Introduced constants in CorsConfiguration
- Removed auto-boxing in CorsRegistration
Prior to this commit, the implementation of getRepeatableAnnotation()
in Spring's AnnotationUtils complied neither with the contract of
getAnnotationsByType() nor with the contract of
getDeclaredAnnotationsByType() as defined in AnnotatedElement in Java 8.
Specifically, unexpected results can be encountered when using Spring's
support for @Repeatable annotations: either annotations show up in the
returned set in the wrong order, or annotations are returned in the set
that should not even be found based on the semantics of @Repeatable.
This commit remedies this problem by deprecating the existing
getRepeatableAnnotation() methods and replacing them with new
getRepeatableAnnotations() and getDeclaredRepeatableAnnotations()
methods that comply with the contracts of Java's getAnnotationsByType()
and getDeclaredAnnotationsByType(), respectively.
Issue: SPR-13068