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
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
Commit #2878ad added the DispatchExceptionHandler contract for
mapping an error before a handler is selected to a HandlerResult.
The same is also convenient for use in HandlerResult itself which
currently uses a java.util.Function essentially for the same.
See gh-22991
This change enables a WebFlux HandlerAdapter to handle not only the
success scenario when a handler is selected, but also any potential
error signal that may occur instead. This makes it possible to
extend ControllerAdvice support to exceptions from handler mapping
such as a 404, 406, 415, and/or even earlier exceptions from the
WebFilter chain.
Closes gh-22991
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
Prior to this commit, several variants of observation documentation
would share the same name; for example HTTP client observations for both
blocking and reactive clients would have the same name.
While it is required that they have the same metric name for dashboards,
the observation documentation names should be different so that they can
be documented without confusing developers.
This commit renames the observation documentation names to avoid that.
Closes gh-29431
This commit fixes the observation instrumentation for the reactive HTTP
server by setting the best matching pattern determined by the web
framework into the `ServerRequestObservationContext`.
This information is required by the observation convention for creating
the expected `KeyValue` for the matching pattern. Prior to this commit,
the information was missing and resulted in an UNKNOWN key value.
Fixes gh-29422
Prior to this commit, the ServerHttpObservationFilter would not add
the current observation as a key in the Reactor context, preventing
from being used or propagated during the HTTP exchange handling.
Also, the client instrumentation in `DefaultWebClient` would start
the observation once the request is fully formed and immutable,
preventing the context from being propagated through HTTP request
headers.
This commit fixes both uses cases now by:
* adding the current observation as a key in the reactor context
on the server side
* using the `ClientRequest.Builder` as a Carrier on the client side
Closes gh-29388
This commit ensures that the ConsumesRequestCondition and
ProducesRequestCondition use a case insensitive check when comparing
parameters.
Closes gh-29416
Add protected, convenience method in ResponseEntityExceptionHandler
to create a ProblemDetail for any exception, along with a
MessageSource lookup for the "detail" field.
Closes gh-29384
This commit introduces support for CBOR and Protobuf using Kotlin
serialization. Support comes in the form of Encoder/Decoder as well
as HttpMessageConverters. Seperate abstract base classes supply support
for binary and string (de)serialization.
The exising JSON codecs and message converters have been migrated to
use the new base classes.
Closes gh-27628
Prior to this commit, the Observation filter for Servlet applications
would only use the request pathInfo as an "http.url" high cardinality
keyvalue. This commit ensures that we're using the full request URL as a
value there.
This also polishes gh-29254.
Fixes gh-29257
See gh-29254
This commit changes the new high cardinality key value from
"uri.expanded" to "http.url" in order to align with the OTel
specification, since there is no need for backwards compatibility on
this new metadata.
Closes gh-29254
Prior to this commit, the HTTP Observations would use
`HttpStatus.Series` as a value source for the "outcome" key value in
recorded observations. This would work for most cases, but would not
align in the 2xx HTTP status cases: the series would provide a
"SUCESSFUL" value whereas the heritage metrics support in Spring Boot
would give "SUCESS".
This commit introduces a dedicated `HttpOutcome` concept for this and
applies it to all HTTP observations.
Fixes gh-29232
This commit ensures that all HTTP `ObservationConvention`
implementations provide a consistent contextual name for observations.
This name should be like "http get" where only the HTTP verb changes
depending on the request.
Fixes gh-29231
This commit fixes an issue in StringDecoder, where, if the buffer did
not contain any delimiters, it was released before it was relayed to
any subscribers.
Closes gh-29119
This commit introduces Micrometer as an API dependency to the
spring-webflux module. Micrometer is used here to instrument `WebClient`
and record `Observation` for HTTP client exchanges.
This replaces Spring Boot's `MetricsWebClientFilterFunction` which
instruments `WebClient` via an `ExchangeFilterFunction`. Here, a direct
instrumentation is more efficient and less prone to metrics errors.
See gh-28341
As of Java 18, the serial lint warning in javac has been expanded to
check for class fields that are not marked as `Serializable`.
See https://www.oracle.com/java/technologies/javase/18all-relnotes.html#JDK-8202056
In the Spring Framework codebase, this can happen with `Map`, `Set` or
`List` attributes which are often assigned with an unmodifiable
implementation variant. Such implementations are `Serializable` but
cannot be used as field types.
This commit ensures that the following changes are applied:
* fields are marked as transient if they can't be serialized
* classes are marked as `Serializable` if this was missing
* `@SuppressWarnings("serial")` is applied where relevant
Prior to this commit, several tests used ClassPathResource#getPath()
based on the knowledge that the ClassPathResource had been created
using the ClassPathResource(String,Class) constructor. However, making
such an assumption seems ill advised in light of the abstraction that
ClassPathResource provides.
In light of that, this commit avoids questionable use of
ClassPathResource#getPath() in tests by refactoring those tests to use
the proper abstractions provided by ClassPathResource.
This commit introduces support for Netty 5's Buffer, in the form of
Netty5DataBuffer. Because of the new API offered by Buffer, several
changes have been made to the DataBuffer API:
- CloseableDataBuffer is a simpler alternative to PooledDataBuffer, and
implemented by Netty5DataBuffer. DataBufferUtils::release can now
handle CloseableDataBuffer as well as PooledDataBuffer.
- PooledDataBuffer::touch has been moved into a separate interface:
TouchableDataBuffer, which is implemented by Netty5DataBuffer.
- The capacity of DataBuffers can no longer be reduced, they can only
grow larger. As a consequence, DataBuffer::capacity(int) has been
deprecated, but ensureWritable (formally ensureCapacity) still exists.
- DataBuffer::slice and retainedSlice have been deprecated in favor of
split, a new method that ensures that memory regions do not overlap.
- DataBuffer::asByteBuffer has been deprecated in favor of toByteBuffer,
a new method that returns a copy, instead of shared data.
- DataBufferFactory::allocateBuffer has been deprecated in favor of
allocateBuffer(int).
Closes gh-28874
Not all HttpHeaders implementations are serializable. This commit
ensures that WebClientRequestException and WebClientResponseException
are serializable, by copying any non-serializable HttpHeaders into a
new, serializable, instance.
Closes gh-28321
Not all HttpHeaders implementations are serializable. This commit
ensures that WebClientRequestException and WebClientResponseException
are serializable, by copying any non-serializable HttpHeaders into a
new, serializable, instance.
Closes gh-28321
Prior to this commit, tests in these two classes intermittently failed
with errors similar to the following, due to concurrent modification
of shared files.
expected:
"<input type="text" id="name" name="name" value="Darren" >"
but was:
"<input type="text" id="name" name="name" value="Darren" >
"hidden"/>"
This commit fixes this by creating a new temporary folder for each test
method invocation.
Ideally one would pass WebClient directly to HttpServiceProxyFactory,
but two need to remain decoupled. This commit adds static, shortcut
methods to WebClientAdapter to create an HttpServiceProxyFactory, thus
eliminating the step to wrap the WebClient.
Prior to this commit, Spring MVC and Spring WebFlux would not support
conditional requests with `If-Match` preconditions. As underlined in the
RFC9110 Section 13.1, those are related to the `If-None-Match`
conditions, but this time only performing requests if the resource
matches the given ETag.
This feature, and in general the `"*"` request Etag, are generally
useful to prevent "lost updates" when performing a POST/PUT request: we
want to ensure that we're updating a version with a known version or
create a new resource only if it doesn't exist already.
This commit adds `If-Match` conditional requests support and ensures
that both `If-Match` and `If-None-Match` work well with `"*"` request
ETags.
We can't rely on `checkNotModified(null)`, as the compiler can't decide
between method variants accepting an ETag `String` or a Last Modified
`long`. Instead, developers should use empty ETags `""` to signal that
no resource is known on the server side.
Closes gh-24881
A static nested class does not keep an implicit reference to its
enclosing instance.
This prevents a common cause of memory leaks and uses less memory per
instance of the class.
Closes gh-28433
Prior to this commit, the `name` attribute in @ModelAttribute was not
supported when using WebFlux. This is because MethodParameter was used
instead of SynthesizingMethodParameter when retrieving the
@ModelAttribute annotation. In other words, @AliasFor was not honored
because the annotation was not synthesized. Consequently, only the
`value` attribute was supported in WebFlux when specifying a custom name
via @ModelAttribute.
This commit fixes this by using SynthesizingMethodParameter to retrieve
the @ModelAttribute annotation.
Closes gh-28423
This commit introduces the PartEvent API. PartEvents are either
- FormPartEvents, representing a form field, or
- FilePartEvents, representing a file upload.
The PartEventHttpMessageReader is a HttpMessageReader that splits
multipart data into a stream of PartEvents. Form fields generate one
FormPartEvent; file uploads produce at least one FilePartEvent. The last
element that makes up a particular part will have isLast set to true.
The PartEventHttpMessageWriter is a HttpMessageWriter that writes a
Publisher<PartEvent> to a outgoing HTTP message. This writer is
particularly useful for relaying a multipart request on the server.
Closes gh-28006
This commit introduces explicit HEAD support in Spring
MVC's ResourceHttpRequestHandler and WebFlux's ResourceWebHandler,
adding just headers but no body.
Closes gh-28291
This commit ensures that any resources created for multipart handling,
obtained via ServerWebExchange.getMultipartData(), are automatically
deleted after handling the completing the response.
Resource for parts obtained via BodyExtractors::toMultipartData and
BodyExtractors::toParts are not cleaned automatically, and
should be cleaned via Part::delete.
Closes gh-27633
This commit contains changes made because of the introduction of
HttpStatusCode. In general, methods that used to return a HttpStatus
now return HttpStatusCode instead, and methods that returned raw status
codes are now deprecated.
See gh-28214
Since the Nashorn JavaScript engine was removed in Java 15, these tests
will never be run on a Java 17+ JDK which is required as of Spring
Framework 6.0.
See gh-27919
This commit makes sure that the response returned by coroutine handler
methods that return ResponseEntity<Flux> is unwrapped correctly.
Closes gh-27809
All Spring MVC exceptions from spring-web, now implement ErrorResponse
and expose HTTP error response information, including an RFC 7807 body.
See gh-27052
ErrorResponse represents a complete error response with status, headers,
and an RFC 7807 ProblemDetail body.
ErrorResponseException implements ErrorResponse and is usable on its
own or as a base class. ResponseStatusException extends
ErrorResponseException and now also supports RFC 7807 and so does its
sub-hierarchy.
ErrorResponse can be returned from `@ExceptionHandler` methods and is
mapped to ResponseEntity.
See gh-27052
ProblemDetail is a representation of an RFC 7807 "problem", and this
commits adds support for it in Spring MVC and WebFlux as a return value
from `@ExceptionHandler` methods, optionally wrapped with
ResponseEntity for headers.
See gh-27052