Since Spring no longer adds the SynthesizedAnnotation interface to the
JDK dynamic proxy used to synthesize an annotation, this commit
officially deprecates SynthesizedAnnotation and related methods in
RuntimeHintsUtils.
See gh-29041, gh-29054
Closes gh-29053
This commit fixes Kotlin Serialization converter
registration logic in RestTemplate,
AbstractMessageBrokerConfiguration and
AllEncompassingFormHttpMessageConverter classes
to be similar to the one in
WebMvcConfigurationSupport.
Closes gh-29008
This commit fixes a race condition in PartGenerator, used by
DefaultPartHttpMessageReader. The condition can occur when a
completion signal comes in, and the state is changed to IdleFileState
at the same time.
Closes gh-28963
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
This commit harmonizes the registration of an executable so that
the default method and the method that takes an empty customizer
produces the same hint. The same applies to the readable flag of
a field hint.
Rather than returning a list of executable modes, the "highest" mode
is retained.
See gh-29011
Based on the feedback in #28977 an easy way to create a list of
type references based on a vararg of classes is helpful when
registering the same hints for several types.
This commit updates RuntimeHintsUtils to focus on registering a JDK
proxy only as annotations of annotated elements that have at least
an introspection hints are visible out-of-the-box.
This commit also removes unnecessary hints and adapt `@Reflective` to
detect if a hint is required using the introduced
MergedAnnotation#isSynthesizable.
See gh-28967
Includes runtime storing of generated classes to a directory specified by the "cglib.generatedClasses" system property. Avoids lazy CGLIB fast-class generation and replaces generated Enhancer and MethodWrapper key classes with equivalent record types. Introduces support for early type determination in InstantiationStrategy, AopProxy and SmartInstantiationAwareBeanPostProcessor - in order to trigger CGLIB class generation in refreshForAotProcessing (through early determineBeanType calls for bean definitions).
Closes gh-28115
This commit correctly identifies MaxUploadSizeExceededException in
StandardMultipartHttpServletRequest by converting keywords in the
exception message to lowercase before checking for their presence, for
compatibility with Jetty 9.4.x.
Closes gh-28759
Prior to this commit, if a cookie was added to MockHttpServletResponse,
the comment attribute was not included in the generated Set-Cookie
header. In addition, MockCookie.parse(String) did not support the
Comment attribute.
This commit addresses both of these issues.
Closes gh-28730
MockHttpServletRequest now checks the requestURI and servletPath to
check whether they imply a Servlet path mapping, which is the case
when the requestURI is longer than the contextPath + servletPath.
This is essential when parsed patterns are in use in which case the
request path is parsed taking into account only the requestURI and
the contextPath. However, if the MappingMatch indicates a match by
Servlet path, then the servletPath is also taken into account.
See gh-28607
As gh-28624 supports only static boolean fields, we still
need a few classes to be initialized at build time.
Such explicit configuration should be in theory avoidable,
so we will work with the GraalVM team to see if this can be
fixed, see for example
https://github.com/oracle/graal/issues/4673
for HttpStatus.
See gh-28624
This commit leverages a subset of @philwebb initial experimentation
to compute at build time the value of specific boolean static fields
in native images. This enhancement is implemented for now as a
GraalVM feature.
The goal here is to keep an optimized footprint via build time code
removal without leveraging build-time class initialization which is known
for the blocking compatibility issues it introduces due to its viral nature.
For now, the static fields initialized at build time with native are:
- NativeDetector#imageCode
- Fields with a name ending by "Present" in "org.springframework" package
typically used for classpath check with ClassUtils#isPresent
Closes gh-28624
ProblemDetail is intended to be extended with additional fields. This
commit removes its "with" methods for chained initialization to keep
it as plain as possible and avoid imposing a particular style on
subclasses.
See gh-27052
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
Includes deprecation of NestedServletException, whereas NestedCheckedException and NestedRuntimeException remain as base classes with several convenience methods.
Closes gh-25162
Support reflection-based serialization of parameters annotated
with @RequestBody and return values annotated with @ResponseBody.
It leverages a new BindingReflectionHintsRegistrar class that
is designed to register transitively the types usually needed
for binding and reflection-based serialization on fields,
constructors and properties. Generics are taken in account
as well.
Closes gh-28518
Prior to this commit, getPort() in HierarchicalUriComponents threw a
NumberFormatException for an invalid port supplied as a String, which
was inconsistent with exception handling elsewhere in the class as well
as within the same method.
This commit introduces a try-catch block in getPort() to consistently
throw IllegalStateExceptions for ports that cannot be parsed.
Closes gh-28521
Prior to this commit, a ClassCastException was thrown for an Optional
return type for an @HttpExchange method. This is because the check for
an Optional return type was based on the type contained in the Optional
instead of the Optional itself.
Closes gh-28493
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
This commit polishes the contribution for support of multiple
base64 segments, and adds supports for multiple quoted printable
segments in Content-Disposition.
Closes gh-28236
This commit removes the dependency that the spring-web module has on
Jakarta Mail.
In FormHttpMessageConverter, a dependency on
jakarta.mail.internet.MimeUtility was replaced by existing encoding
logic in ContentDisposition.
In StandardMultipartHttpServletRequest, a dependency on the same
MimeUtility was replaced by new quoted-printable decoding logic in
ContentDisposition.
Closes gh-28392
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 makes sure that TomcatServerHttpRequest::readFromInputStream
follows the same contract as the method it overrides, and returns
AbstractListenerReadPublisher.EMPTY_BUFFER when 0 bytes are read.
See gh-28241
This commit fixes a regression that added the Accept-Ranges header on
both client and server. Accept-Ranges is response header, so we now make
sure it only appears on the server side.
See gh-28291
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
If we read 0 bytes, e.g. chunked encoding markup read but not the
actual data within it, don't stop reading since the server may or
may not consider it necessary to call onDataAvailable again.
Instead, we keep on reading, and although isReady likely returns
false on the next iteration, it eliminates ambiguity and ensures
the server will call onDataAvailable when more data arrives.
Closes gh-28241
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
This commit introduces HttpStatusCode, an interface implemented by
HttpStatus. Instances of HttpStatusCode are obtained via static
valueOf(int) factory method, returning a HttpStatus enum entry if
available, and a default implementation otherwise.
The underlying reason behind this change is HTTP status codes are not
enumerable, but instead range from 100-999.
Closes gh-28214
With a Java 8 baseline in place for quite some time now, it no longer
makes sense to refer to features such as annotations as "Java 5
annotations".
This commit also removes old `Tiger*Tests` classes, thereby avoiding
duplicate execution of various tests.
Prior to this commit, `AsyncRestTemplate` would log errors (including
simple 404s) with WARN level. Such errors are quite common and should
not clutter logs.
This commit aligns the logging strategy with RestTemplate, using the
DEBUG level for such cases.
Fixes gh-28049
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
SocketUtils was introduced in Spring Framework 4.0, primarily to assist
in writing integration tests which start an external server on an
available random port. However, these utilities make no guarantee about
the subsequent availability of a given port and are therefore
unreliable. Instead of using SocketUtils to find an available local
port for a server, it is recommended that users rely on a server's
ability to start on a random port that it selects or is assigned by the
operating system. To interact with that server, the user should query
the server for the port it is currently using.
SocketUtils is now deprecated in 5.3.16 and will be removed in 6.0.
Closes gh-28052
In a small minority of cases, the multipart boundary can spread across
three incoming buffers.
Prior to this commit, MultipartParser.BodyState only supported two
buffers. If the boundary is spread across three buffers, the first
buffer of the three is sent as a whole, even though it contains the
first bytes of the boundary.
This commit fixes this bug, by enqueuing all prior buffers in a queue,
and emitting the ones that cannot contain boundary bytes.
Closes gh-27939
The failing test is for Apache HttpComponents where we cannot apply the
Content-Length together with other headers, and must pass it instead
explicitly to ReactiveEntityProducer when writing at which point it gets
set in the native headers.
Closes gh-27768
NettyHeadersAdapter::putAll uses HttpHeaders::add, which does not
overwrite existing headers. putAll should use HttpHeaders::set instead,
just like NettyHeadersAdapter::put does.
Closes gh-27887
Where unfeasible, this commit adds inline comments to explain why
try-with-resources must not be used in certain scenarios. The purpose
of the comments is to avoid accidental conversion to try-with-resources
at a later date.
Closes gh-27823
With JDK 9, java.util.regex.Matcher received overloaded variants of
appendReplacement() and appendTail() that accept a StringBuilder,
allowing us to replace the use of StringBuffer with StringBuilder.
Closes gh-27822
This commit replaces the use of Collections.unmodifiableList/Set/Map
with the corresponding 'of(...)' factory methods introduced in Java 9.
Closes gh-27824