Support multipart/mixed and related in DefaultServerWebExchange
See gh-29671
This commit is contained in:
parent
17bc3facaa
commit
67df0756cd
|
@ -613,8 +613,8 @@ The `DefaultServerWebExchange` uses the configured `HttpMessageReader` to parse
|
|||
----
|
||||
|
||||
The `DefaultServerWebExchange` uses the configured
|
||||
`HttpMessageReader<MultiValueMap<String, Part>>` to parse `multipart/form-data` content
|
||||
into a `MultiValueMap`.
|
||||
`HttpMessageReader<MultiValueMap<String, Part>>` to parse `multipart/form-data`,
|
||||
`multipart/mixed` and `multipart/related` content into a `MultiValueMap`.
|
||||
By default, this is the `DefaultPartHttpMessageReader`, which does not have any third-party
|
||||
dependencies.
|
||||
Alternatively, the `SynchronossPartHttpMessageReader` can be used, which is based on the
|
||||
|
@ -805,9 +805,9 @@ consistently for access to the cached form data versus reading from the raw requ
|
|||
==== Multipart
|
||||
|
||||
`MultipartHttpMessageReader` and `MultipartHttpMessageWriter` support decoding and
|
||||
encoding "multipart/form-data" content. In turn `MultipartHttpMessageReader` delegates to
|
||||
another `HttpMessageReader` for the actual parsing to a `Flux<Part>` and then simply
|
||||
collects the parts into a `MultiValueMap`.
|
||||
encoding "multipart/form-data", "multipart/mixed" and "multipart/related" content.
|
||||
In turn `MultipartHttpMessageReader` delegates to another `HttpMessageReader`
|
||||
for the actual parsing to a `Flux<Part>` and then simply collects the parts into a `MultiValueMap`.
|
||||
By default, the `DefaultPartHttpMessageReader` is used, but this can be changed through the
|
||||
`ServerCodecConfigurer`.
|
||||
For more information about the `DefaultPartHttpMessageReader`, refer to the
|
||||
|
|
|
@ -163,9 +163,11 @@ public class DefaultServerWebExchange implements ServerWebExchange {
|
|||
|
||||
try {
|
||||
MediaType contentType = request.getHeaders().getContentType();
|
||||
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
|
||||
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType) ||
|
||||
MediaType.MULTIPART_MIXED.isCompatibleWith(contentType) ||
|
||||
MediaType.MULTIPART_RELATED.isCompatibleWith(contentType)) {
|
||||
return ((HttpMessageReader<MultiValueMap<String, Part>>) configurer.getReaders().stream()
|
||||
.filter(reader -> reader.canRead(MULTIPART_DATA_TYPE, MediaType.MULTIPART_FORM_DATA))
|
||||
.filter(reader -> reader.canRead(MULTIPART_DATA_TYPE, contentType))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException("No multipart HttpMessageReader.")))
|
||||
.readMono(MULTIPART_DATA_TYPE, request, Hints.from(Hints.LOG_PREFIX_HINT, logPrefix))
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.springframework.http.ResponseEntity;
|
|||
import org.springframework.http.codec.multipart.FilePart;
|
||||
import org.springframework.http.codec.multipart.FormFieldPart;
|
||||
import org.springframework.http.codec.multipart.Part;
|
||||
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
@ -55,14 +56,38 @@ class MultipartHttpHandlerIntegrationTests extends AbstractHttpHandlerIntegratio
|
|||
}
|
||||
|
||||
@ParameterizedHttpServerTest
|
||||
void getFormParts(HttpServer httpServer) throws Exception {
|
||||
void getFormPartsFormdata(HttpServer httpServer) throws Exception {
|
||||
performTest(httpServer, MediaType.MULTIPART_FORM_DATA);
|
||||
}
|
||||
|
||||
@ParameterizedHttpServerTest
|
||||
void getFormPartsMixed(HttpServer httpServer) throws Exception {
|
||||
performTest(httpServer, MediaType.MULTIPART_MIXED);
|
||||
}
|
||||
|
||||
@ParameterizedHttpServerTest
|
||||
void getFormPartsRelated(HttpServer httpServer) throws Exception {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
restTemplate.getMessageConverters().stream()
|
||||
.filter(FormHttpMessageConverter.class::isInstance)
|
||||
.map(FormHttpMessageConverter.class::cast)
|
||||
.findFirst()
|
||||
.orElseThrow()
|
||||
.addSupportedMediaTypes(MediaType.MULTIPART_RELATED);
|
||||
performTest(httpServer, MediaType.MULTIPART_RELATED, restTemplate);
|
||||
}
|
||||
|
||||
private void performTest(HttpServer httpServer, MediaType mediaType) throws Exception {
|
||||
performTest(httpServer, mediaType, new RestTemplate());
|
||||
}
|
||||
|
||||
private void performTest(HttpServer httpServer, MediaType mediaType, RestTemplate restTemplate) throws Exception {
|
||||
startServer(httpServer);
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
RequestEntity<MultiValueMap<String, Object>> request = RequestEntity
|
||||
.post(URI.create("http://localhost:" + port + "/form-parts"))
|
||||
.contentType(MediaType.MULTIPART_FORM_DATA)
|
||||
.contentType(mediaType)
|
||||
.body(generateBody());
|
||||
ResponseEntity<Void> response = restTemplate.exchange(request, Void.class);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
|
Loading…
Reference in New Issue