This is a follow-up change related to gh-31104.
This change reverts the changes previously made in
`ExceptionHandlerExceptionResolver` and instead attempts to reset the
response directly in `DispatcherServlet` in order to cover all types or
exception handling.
Unlike the previous change, we decided to continue even if the response
was already committed: exception handlers will have a chance to be
called, even if it means they'll have to operate on a garbled response.
This change will cause less disruption, in case existing exception
handlers were relying on this behavior.
See gh-31104
Prior to this commit, the `ExceptionHandlerExceptionResolver` would
resolve exceptions and handle them by writing to the HTTP response body,
even if the request was already partially handled and content was
written to the response body.
This could result in HTTP responses with some content for the intended
application response, then other content for the handled exception.
This would happen especially when the error would be raised while
writing to the response (for example when serializing content).
This commit attempts to reset the HTTP response before handling the
exception. This effectively resets the response buffer for the body as
well as response headers. If the response is already committed, the
Servlet container raises an exception and the exception handling is
skipped altogether in order to avoid garbled responses.
Closes gh-31104
This commit changes the `synchronized` usage into a `ReentrantLock`, in
order to guard write operations with a construct that does not pin
virtual threads to the current platform thread on JDK21.
Closes gh-30996
Prior to this commit, the `SseEventBuilder` would be used to create SSE
events and write them to the connection using the `ResponseBodyEmitter`.
This would send each data item one by one, effectively writing and
flushing to the network for each. Since multiple data lines are prepared
by the `SseEventBuilder`, a typical write of an SSE event performs
multiple flushes operations.
This commit adds a method on `ResponseBodyEmitter` to perform batch
writes (given a `Set<DataWithMediaType>`) and only flush once all
elements of the set have been written.
This also applies in case of early writes, where now all buffered
elements are written then flushed altogether.
Fixes gh-30912
Prior to this commit, MappedInterceptor had a getPathPatterns() method
that returned the include patterns.
This commit introduces getIncludePathPatterns() (which effectively
replaces getPathPatterns()) and getExcludePathPatterns(). In addition,
this commit deprecates getPathPatterns().
Closes gh-30971
This commit ensures that ServerResponse.HeadersBuilder::build can throw
an exception, by introducing a separate functional interface that does
allow for exceptions to be thrown.
Closes gh-30818
As a consequence, the spring-messaging HandlerMethod detects interface parameter annotations as well, and the same is available for other HandlerMethod variants.
Closes gh-30801
To handle method validation errors in ResponseEntityExceptionHandler,
MethodValidationException and associated types should not depend on
Bean Validation. To that effect:
1. MethodValidationResult and ParameterValidationResult no longer make
the underlying ConstraintViolation set available, and instead expose
only the adapted validation errors (MessageSourceResolvable, Errors),
analogous to what SpringValidatorAdapter does. And likewise
MethodValidationException no longer extends ConstraintViolationException.
2. MethodValidationPostProcessor has a new property
adaptConstraintViolations to decide whether to simply raise
ConstraintViolationException, or otherwise to adapt the ConstraintViolations
and raise MethodValidationException instead, with the former is the default
for compatibility.
3. As a result, the MethodValidator contract can now expose methods that
return MethodValidationResult, which provided more flexibility for handling,
and it allows MethodValidationAdapter to implement MethodValidator directly.
4. Update Javadoc in method validation classes to reflect this shift, and
use terminology consistent with Spring validation in classes without an
explicit dependency on Bean Validation.
See gh-30644
This commit adds support for Kotlin parameter default values
in handler methods. It allows to write:
@RequestParam value: String = "default"
as an alternative to:
@RequestParam(defaultValue = "default") value: String
Both Spring MVC and WebFlux are supported, including on
suspending functions.
Closes gh-21139
This commit changes the order of RouterFunctionMapping defined
in WebMvcConfigurationSupport from 3 to -1 in order to achieve
better consistency between WebMVC and WebFlux. It also reduces
the surprise factor. That way, functional routes are always
before annotation-based ones.
Closes gh-30278
This commit polishes the previous change, ensuring that if the request
uses a wildcard subtype with an ndjson suffix then the wildcard isn't
present in the response's Content-Type.
Insteand, in that case we would fall back to `applicatin/x-ndjson` (the
base ndjson media type), assuming that the requester is only interested
in the ndjson nature of the underlying representation and not in the
specific semantics of any subtype.
See commit 9332b3f
See gh-26817
This commit adds `application/*+x-ndjson`, a wildcard media type which
covers all types that can be parsed as nd-json, to the list of media
types the ReactiveTypeHandler considers for a streaming response in
WebMVC.
As a result, a request which for example `Accept` the
`application/vnd.myapp.v1+x-ndjson` media type will generate a response
with the same `Content-Type`, with newline-delimited json objects being
streamed in the response body.
Closes gh-26817
Prior to this commit, some FreeMarker tests would fail when involving
property lookup in a template file, where this bean property is linked
with a method implemented as a default method on an interface.
While I did not manage to reproduce this behavior in an independent test
case, this is most likely related to a change in JDK 21:
https://bugs.openjdk.org/browse/JDK-8071693
This commit changes the template expression to using the default method
directly.
This commit ensures that HTTP headers like "text/event-stream"
are correctly forwarded to the converter used in
SseServerResponse for proper pretty print handling.
Close gh-30277
This commit refactors some AssertJ assertions into more idiomatic and
readable ones. Using the dedicated assertion instead of a generic one
will produce more meaningful error messages.
For instance, consider collection size:
```
// expected: 5 but was: 2
assertThat(collection.size()).equals(5);
// Expected size: 5 but was: 2 in: [1, 2]
assertThat(collection).hasSize(5);
```
Closes gh-30104
This commit ensures that WebFlux's RequestMethodsRequestCondition
supports HTTP methods that are not in the RequestMethod enum.
- RequestMethod::resolve is introduced, to convert from a HttpMethod
(name) to enum values.
- RequestMethod::asHttpMethod is introduced, to convert from enum value
to HttpMethod.
- HttpMethod::valueOf replaced Map-based lookup to a switch statement
- Enabled tests that check for WebDAV methods
See gh-27697
Closes gh-29981
This commit makes several changes to PR #24651.
- Add byte[] getContentAsByteArray() on Resource.
- Remove getContentAsString() from Resource, as it relied on the default
charset which is not reliable.
- Add getContentAsString() to EncodedResource, as a charset is provided
through the constructor.
See gh-24651
Add constructors to HttpMediaTypeNotSupportedException and
UnsupportedMediaTypeStatusException for a parse error that also accept
the list of supported media types to include in the response headers.
Closes gh-28062
When comparing empty ProducesRequestCondition, compareTo would throw an
IllegalStateException if the Accept header was invalid. This commit
fixes that behavior.
Closes gh-29794
This commit ensures that HTTP methods not supported by HttpServlet, for
instance WebDAV methods, are still supported in FrameworkServlet.
Closes gh-29689
This ensures that by default the reason is used to set the "detail"
field. It's a follow-up fix to a27f2e994b
which resolved the issue partially.
Closes gh-29608
LocalVariableTableParameterNameDiscoverer is not registered by default anymore now.
Java sources should be compiled with `-parameters` instead (available since Java 8).
Also retaining standard Java parameter names for all of Spring's Kotlin sources now.
Closes gh-29531
As a follow-up to gh-29277, and since the JAXB support is now
triggered by the classpath presence of a JAXB implementation,
it makes sense to make SourceHttpMessageConverter, previously
configured unconditionally, optional.
That makes a big difference on native (1M of RSS reduction
with current typical Spring Boot 3 arrangement, 3.4M when
other usages of XML are not reachable).
It also brings more consistency between Spring MVC
and Spring WebFlux, and means that XML support for
Spring web applications now needs to be enabled explicitly.
As a consequence, Spring web applications using
javax.xml.transform.Source now needs to configure
SourceHttpMessageConverter explicitly in RestTemplate or
Spring MVC.
Closes gh-29535
This commit removes specific version info from Jackson codecs and
converters, in favor of generic info or removing the version information
all together.
See gh-29508
Prior to this commit, the server observability support would create a
cycle in Java packages.
This commit refactors the current arrangement to solve this by:
* "flattening" the reactive HTTP instrumentation; this removes the
dependency to the `ServerWebExchange` and `PathPattern` types
* moving the `observation` package under
`org.springframework.http.server` and
`org.springframework.http.server.reactive`
See gh-29477
This commit reverts changes to AbstractCacheManager since iterating
over the caches in a for-loop and a stream is duplicated effort.
This commit reverts changes to DefaultRenderingResponseBuilder,
RouterFunctions, and OriginHandshakeInterceptor since order matters for
those use cases: they were originally based on the semantics of
LinkedHashSet or LinkedHashMap; whereas, Set.copyOf() and Map.copyOf()
do not provide any guarantees regarding ordering.
This commit also applies analogous changes to "sibling" implementations
across Servlet mocks as well as Web MVC and WebFlux.
See gh-29321
Includes corresponding build upgrade to Tomcat 10.1.1 and Undertow 2.3.0
(while retaining runtime compatibility with Tomcat 10.0 and Undertow 2.2)
Closes gh-29435
Closes gh-29436
This commit ensures that the ConsumesRequestCondition and
ProducesRequestCondition use a case insensitive check when comparing
parameters.
Closes gh-29416