diff --git a/spring-web/src/main/java/org/springframework/http/codec/ClientCodecConfigurer.java b/spring-web/src/main/java/org/springframework/http/codec/ClientCodecConfigurer.java
index 070b0610ee1f..cfba0520ea88 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/ClientCodecConfigurer.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/ClientCodecConfigurer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
package org.springframework.http.codec;
import org.springframework.core.codec.Decoder;
-import org.springframework.core.codec.Encoder;
/**
* Extension of {@link CodecConfigurer} for HTTP message reader and writer
@@ -83,13 +82,6 @@ static ClientCodecConfigurer create() {
*/
interface ClientDefaultCodecs extends DefaultCodecs {
- /**
- * Configure encoders or writers for use with
- * {@link org.springframework.http.codec.multipart.MultipartHttpMessageWriter
- * MultipartHttpMessageWriter}.
- */
- MultipartCodecs multipartCodecs();
-
/**
* Configure the {@code Decoder} to use for Server-Sent Events.
*
By default if this is not set, and Jackson is available, the
@@ -102,26 +94,4 @@ interface ClientDefaultCodecs extends DefaultCodecs {
void serverSentEventDecoder(Decoder> decoder);
}
-
- /**
- * Registry and container for multipart HTTP message writers.
- */
- interface MultipartCodecs {
-
- /**
- * Add a Part {@code Encoder}, internally wrapped with
- * {@link EncoderHttpMessageWriter}.
- * @param encoder the encoder to add
- */
- MultipartCodecs encoder(Encoder> encoder);
-
- /**
- * Add a Part {@link HttpMessageWriter}. For writers of type
- * {@link EncoderHttpMessageWriter} consider using the shortcut
- * {@link #encoder(Encoder)} instead.
- * @param writer the writer to add
- */
- MultipartCodecs writer(HttpMessageWriter> writer);
- }
-
}
diff --git a/spring-web/src/main/java/org/springframework/http/codec/CodecConfigurer.java b/spring-web/src/main/java/org/springframework/http/codec/CodecConfigurer.java
index a27b0709a3aa..a5906a49b697 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/CodecConfigurer.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/CodecConfigurer.java
@@ -258,6 +258,24 @@ interface DefaultCodecs {
* @since 5.1
*/
void enableLoggingRequestDetails(boolean enable);
+
+ /**
+ * Configure encoders or writers for use with
+ * {@link org.springframework.http.codec.multipart.MultipartHttpMessageWriter
+ * MultipartHttpMessageWriter}.
+ * @since 6.0.3
+ */
+ MultipartCodecs multipartCodecs();
+
+ /**
+ * Configure the {@code HttpMessageReader} to use for multipart requests.
+ *
Note that {@link #maxInMemorySize(int)} and/or
+ * {@link #enableLoggingRequestDetails(boolean)}, if configured, will be
+ * applied to the given reader, if applicable.
+ * @param reader the message reader to use for multipart requests.
+ * @since 6.0.3
+ */
+ void multipartReader(HttpMessageReader> reader);
}
@@ -389,4 +407,27 @@ interface DefaultCodecConfig {
Boolean isEnableLoggingRequestDetails();
}
+
+ /**
+ * Registry and container for multipart HTTP message writers.
+ * @since 6.0.3
+ */
+ interface MultipartCodecs {
+
+ /**
+ * Add a Part {@code Encoder}, internally wrapped with
+ * {@link EncoderHttpMessageWriter}.
+ * @param encoder the encoder to add
+ */
+ MultipartCodecs encoder(Encoder> encoder);
+
+ /**
+ * Add a Part {@link HttpMessageWriter}. For writers of type
+ * {@link EncoderHttpMessageWriter} consider using the shortcut
+ * {@link #encoder(Encoder)} instead.
+ * @param writer the writer to add
+ */
+ MultipartCodecs writer(HttpMessageWriter> writer);
+ }
+
}
diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java b/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java
index c6f9222a19c0..767ab738e0d2 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -82,16 +82,6 @@ static ServerCodecConfigurer create() {
*/
interface ServerDefaultCodecs extends DefaultCodecs {
- /**
- * Configure the {@code HttpMessageReader} to use for multipart requests.
- *
Note that {@link #maxInMemorySize(int)} and/or
- * {@link #enableLoggingRequestDetails(boolean)}, if configured, will be
- * applied to the given reader, if applicable.
- * @param reader the message reader to use for multipart requests.
- * @since 5.1.11
- */
- void multipartReader(HttpMessageReader> reader);
-
/**
* Configure the {@code Encoder} to use for Server-Sent Events.
*
By default if this is not set, and Jackson is available, the
diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriter.java
index 777b5991ab86..b4fca60dd935 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriter.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriter.java
@@ -79,7 +79,7 @@ public class MultipartHttpMessageWriter extends MultipartWriterSupport
private static final Map DEFAULT_HINTS = Hints.from(Hints.SUPPRESS_LOGGING_HINT, true);
- private final List> partWriters;
+ private final Supplier>> partWritersSupplier;
@Nullable
private final HttpMessageWriter> formWriter;
@@ -112,8 +112,23 @@ public MultipartHttpMessageWriter(List> partWriters) {
public MultipartHttpMessageWriter(List> partWriters,
@Nullable HttpMessageWriter> formWriter) {
+ this(() -> partWriters, formWriter);
+ }
+
+ /**
+ * Constructor with a supplier for an explicit list of writers for
+ * serializing parts and a writer for plain form data to fall back when
+ * no media type is specified and the actual map consists of String
+ * values only.
+ * @param partWritersSupplier the supplier for writers for serializing parts
+ * @param formWriter the fallback writer for form data, {@code null} by default
+ * @since 6.0.3
+ */
+ public MultipartHttpMessageWriter(Supplier>> partWritersSupplier,
+ @Nullable HttpMessageWriter> formWriter) {
+
super(initMediaTypes(formWriter));
- this.partWriters = partWriters;
+ this.partWritersSupplier = partWritersSupplier;
this.formWriter = formWriter;
}
@@ -131,7 +146,7 @@ private static List initMediaTypes(@Nullable HttpMessageWriter> for
* @since 5.0.7
*/
public List> getPartWriters() {
- return Collections.unmodifiableList(this.partWriters);
+ return Collections.unmodifiableList(this.partWritersSupplier.get());
}
@@ -264,8 +279,8 @@ else if (resolvableType.resolve() == Resource.class) {
MediaType contentType = headers.getContentType();
- final ResolvableType finalBodyType = resolvableType;
- Optional> writer = this.partWriters.stream()
+ ResolvableType finalBodyType = resolvableType;
+ Optional> writer = this.partWritersSupplier.get().stream()
.filter(partWriter -> partWriter.canWrite(finalBodyType, contentType))
.findFirst();
diff --git a/spring-web/src/main/java/org/springframework/http/codec/support/BaseCodecConfigurer.java b/spring-web/src/main/java/org/springframework/http/codec/support/BaseCodecConfigurer.java
index 4eed384a6413..3b7b4ddb2e23 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/support/BaseCodecConfigurer.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/support/BaseCodecConfigurer.java
@@ -55,6 +55,7 @@ abstract class BaseCodecConfigurer implements CodecConfigurer {
Assert.notNull(defaultCodecs, "'defaultCodecs' is required");
this.defaultCodecs = defaultCodecs;
this.customCodecs = new DefaultCustomCodecs();
+ this.defaultCodecs.setPartWritersSupplier(this::getWriters);
}
/**
@@ -64,6 +65,7 @@ abstract class BaseCodecConfigurer implements CodecConfigurer {
protected BaseCodecConfigurer(BaseCodecConfigurer other) {
this.defaultCodecs = other.cloneDefaultCodecs();
this.customCodecs = new DefaultCustomCodecs(other.customCodecs);
+ this.defaultCodecs.setPartWritersSupplier(this::getWriters);
}
/**
diff --git a/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java b/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java
index 9cfe0f3d7fb6..05c4c0f4a4d1 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java
@@ -21,6 +21,7 @@
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
+import java.util.function.Supplier;
import org.springframework.core.codec.AbstractDataBufferDecoder;
import org.springframework.core.codec.ByteArrayDecoder;
@@ -62,6 +63,8 @@
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
import org.springframework.http.codec.multipart.PartEventHttpMessageReader;
+import org.springframework.http.codec.multipart.PartEventHttpMessageWriter;
+import org.springframework.http.codec.multipart.PartHttpMessageWriter;
import org.springframework.http.codec.protobuf.KotlinSerializationProtobufDecoder;
import org.springframework.http.codec.protobuf.KotlinSerializationProtobufEncoder;
import org.springframework.http.codec.protobuf.ProtobufDecoder;
@@ -160,6 +163,15 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
@Nullable
private Encoder> kotlinSerializationProtobufEncoder;
+ @Nullable
+ private DefaultMultipartCodecs multipartCodecs;
+
+ @Nullable
+ private Supplier>> partWritersSupplier;
+
+ @Nullable
+ private HttpMessageReader> multipartReader;
+
@Nullable
private Consumer