mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Merge branch '6.2.x'
This commit is contained in:
@@ -3,7 +3,10 @@
|
||||
|
||||
[.small]#xref:web/webflux/reactive-spring.adoc#webflux-filters[See equivalent in the Reactive stack]#
|
||||
|
||||
The `spring-web` module provides some useful filters:
|
||||
In the Servlet API, you can add a `jakarta.servlet.Filter` to apply interception-style logic
|
||||
before and after the rest of the processing chain of filters and the target `Servlet`.
|
||||
|
||||
The `spring-web` module has a number of built-in `Filter` implementations:
|
||||
|
||||
* xref:web/webmvc/filters.adoc#filters-http-put[Form Data]
|
||||
* xref:web/webmvc/filters.adoc#filters-forwarded-headers[Forwarded Headers]
|
||||
@@ -11,9 +14,19 @@ The `spring-web` module provides some useful filters:
|
||||
* xref:web/webmvc/filters.adoc#filters-cors[CORS]
|
||||
* xref:web/webmvc/filters.adoc#filters.url-handler[URL Handler]
|
||||
|
||||
Servlet filters can be configured in the `web.xml` configuration file or using Servlet annotations.
|
||||
If you are using Spring Boot, you can
|
||||
{spring-boot-docs}/how-to/webserver.html#howto.webserver.add-servlet-filter-listener.spring-bean[declare them as beans and configure them as part of your application].
|
||||
There are also base class implementations for use in Spring applications:
|
||||
|
||||
* `GenericFilterBean` -- base class for a `Filter` configured as a Spring bean;
|
||||
integrates with the Spring `ApplicationContext` lifecycle.
|
||||
* `OncePerRequestFilter` -- extension of `GenericFilterBean` that supports a single
|
||||
invocation at the start of a request, i.e. during the `REQUEST` dispatch phase, and
|
||||
ignoring further handling via `FORWARD` dispatches. The filter also provides control
|
||||
over whether the `Filter` gets involved in `ASYNC` and `ERROR` dispatches.
|
||||
|
||||
Servlet filters can be configured in `web.xml` or via Servlet annotations.
|
||||
In a Spring Boot application , you can
|
||||
{spring-boot-docs}/how-to/webserver.html#howto.webserver.add-servlet-filter-listener.spring-bean[declare Filter's as beans]
|
||||
and Boot will have them configured.
|
||||
|
||||
|
||||
[[filters-http-put]]
|
||||
|
||||
@@ -22,10 +22,16 @@ import java.io.OutputStream;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* Represents an HTTP output message that allows for setting a streaming body.
|
||||
* Note that such messages typically do not support {@link #getBody()} access.
|
||||
* Contract for {@code HttpOutputMessage} implementations to expose the ability
|
||||
* to stream request body content by writing to an {@link OutputStream} from
|
||||
* a callback.
|
||||
*
|
||||
* <p>The {@link #setBody(Body)} method provides the option to stream, and is
|
||||
* mutually exclusive use of {@link #getBody()}, which instead returns an
|
||||
* {@code OutputStream} that aggregates the request body before sending it.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
* @see #setBody
|
||||
*/
|
||||
@@ -33,6 +39,8 @@ public interface StreamingHttpOutputMessage extends HttpOutputMessage {
|
||||
|
||||
/**
|
||||
* Set the streaming body callback for this message.
|
||||
* <p>Note that this is mutually exclusive with {@link #getBody()}, which
|
||||
* may instead aggregate the request body before sending it.
|
||||
* @param body the streaming body callback
|
||||
*/
|
||||
void setBody(Body body);
|
||||
@@ -60,9 +68,9 @@ public interface StreamingHttpOutputMessage extends HttpOutputMessage {
|
||||
|
||||
|
||||
/**
|
||||
* Defines the contract for bodies that can be written directly to an
|
||||
* {@link OutputStream}. Useful with HTTP client libraries that provide
|
||||
* indirect access to an {@link OutputStream} via a callback mechanism.
|
||||
* Contract to stream request body content to an {@link OutputStream}.
|
||||
* In some HTTP client libraries this is only possible indirectly through a
|
||||
* callback mechanism.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface Body {
|
||||
|
||||
+25
-6
@@ -22,16 +22,23 @@ import java.io.OutputStream;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.StreamingHttpOutputMessage;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* Abstract base for {@link ClientHttpRequest} that also implement
|
||||
* {@link StreamingHttpOutputMessage}. Ensures that headers and
|
||||
* body are not written multiple times.
|
||||
* Extension of {@link AbstractClientHttpRequest} that adds the ability to stream
|
||||
* request body content directly to the underlying HTTP client library through
|
||||
* the {@link StreamingHttpOutputMessage} contract.
|
||||
*
|
||||
* <p>It is necessary to call {@link #setBody} and stream the request body through
|
||||
* a callback for access to the {@code OutputStream}. The alternative to call
|
||||
* {@link #getBody()} is also supported as a fallback, but that does not stream,
|
||||
* and returns an aggregating {@code OutputStream} instead.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 6.1
|
||||
*/
|
||||
abstract class AbstractStreamingClientHttpRequest extends AbstractClientHttpRequest
|
||||
@@ -42,6 +49,12 @@ abstract class AbstractStreamingClientHttpRequest extends AbstractClientHttpRequ
|
||||
private @Nullable FastByteArrayOutputStream bodyStream;
|
||||
|
||||
|
||||
/**
|
||||
* Implements the {@link HttpOutputMessage} contract for request body content.
|
||||
* <p>Note that this method does not result in streaming, and the returned
|
||||
* {@code OutputStream} aggregates the full content in a byte[] before
|
||||
* sending. To use streaming, call {@link #setBody} instead.
|
||||
*/
|
||||
@Override
|
||||
protected final OutputStream getBodyInternal(HttpHeaders headers) {
|
||||
Assert.state(this.body == null, "Invoke either getBody or setBody; not both");
|
||||
@@ -52,6 +65,10 @@ abstract class AbstractStreamingClientHttpRequest extends AbstractClientHttpRequ
|
||||
return this.bodyStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the {@link StreamingHttpOutputMessage} contract for writing
|
||||
* request body by streaming directly to the underlying HTTP client.
|
||||
*/
|
||||
@Override
|
||||
public final void setBody(Body body) {
|
||||
Assert.notNull(body, "Body must not be null");
|
||||
@@ -72,12 +89,14 @@ abstract class AbstractStreamingClientHttpRequest extends AbstractClientHttpRequ
|
||||
|
||||
|
||||
/**
|
||||
* Abstract template method that writes the given headers and content to the HTTP request.
|
||||
* @param headers the HTTP headers
|
||||
* Abstract method for concrete implementations to write the headers and
|
||||
* {@link StreamingHttpOutputMessage.Body} to the HTTP request.
|
||||
* @param headers the HTTP headers for the request
|
||||
* @param body the HTTP body, may be {@code null} if no body was {@linkplain #setBody(Body) set}
|
||||
* @return the response object for the executed request
|
||||
* @since 6.1
|
||||
*/
|
||||
protected abstract ClientHttpResponse executeInternal(HttpHeaders headers, @Nullable Body body) throws IOException;
|
||||
protected abstract ClientHttpResponse executeInternal(
|
||||
HttpHeaders headers, @Nullable Body body) throws IOException;
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.web.client;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
|
||||
/**
|
||||
@@ -44,6 +45,12 @@ public interface RequestCallback {
|
||||
* Gets called by {@link RestTemplate#execute} with an opened {@code ClientHttpRequest}.
|
||||
* Does not need to care about closing the request or about handling errors:
|
||||
* this will all be handled by the {@code RestTemplate}.
|
||||
* <p><strong>Note:</strong> In order to stream request body content directly
|
||||
* to the underlying HTTP library, implementations must check if the request
|
||||
* is an implementation of {@link org.springframework.http.StreamingHttpOutputMessage},
|
||||
* and set the request body through it. Use of the {@link HttpOutputMessage#getBody()}
|
||||
* is also supported, but results in full content aggregation prior to execution.
|
||||
* All built-in request implementations support {@code StreamingHttpOutputMessage}.
|
||||
* @param request the active HTTP request
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user