How to parse Multiparts response body from client side in Spring Boot?
DefaultHttpMessageReader
for parsing"multipart/form-data"
requests to a stream ofPart
s.
In default, non-streaming mode, this message reader stores the contents of parts smaller thanmaxInMemorySize
in memory, and parts larger than that to a temporary file infileStorageDirectory
.
This reader can be provided to MultipartHttpMessageReader
in order to aggregate all parts into a Map.
use toEntityFlux and DefaultPartHttpMessageReader for Reactive stack
Variant of toEntityFlux(Class) with a BodyExtractor.
Params:
bodyExtractor – the BodyExtractor that reads from the response
Type parameters:
– the body element type
Returns:
the ResponseEntity
Since:
5.3.2
webclient.get()
.uri(...uri)
.headers(...headers)
.retrieve()
.toEntityFlux((inputMessage, context) -> partReader.read(ResolvableType.forType(byte[].class), inputMessage, Map.of()))
.map(ResponseEntity::getBody)
.flatMap(parts -> parts.reduce(MixedResponse.builder(), (body, part) -> {
if (part.headers().getContentType().equals(MediaType.APPLICATION_JSON)) {
val json = DataBufferUtils.join(part.content())
.map(buffer -> {
byte[] bytes = new byte[buffer.readableByteCount()];
buffer.read(bytes);
DataBufferUtils.release(buffer);
return jsonValueSerializer.deserializeValue(new String(bytes),
JSON.class);
});
body.json(json);
}
if (part.headers().getContentType().equals(MediaType.APPLICATION_PDF)) {
var pdf = DataBufferUtils.join(part.content())
.map(buffer -> buffer.asByteBuffer().array());
body.pdf(pdf);
}
return body;
})
.map(body -> body.build()));
NOTE that the body contents must be completely consumed, relayed, or released to avoid memory leaks.
custom HttpMessageConverter for the RestTemplate
You might have to custom your own HttpMessageConverter and add into the RestTemplate message converters.
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MultiPartMessageConverter(objectMapper));
final ResponseEntity<ResultModel> responseEntity = restTemplate.getForEntity("http://localhost:" + randomServerPort + "/test", ResultModel.class);
final ResultModel resultModel = responseEntity.getBody();
Assertions.assertNotNull(resultModel);
Assertions.assertEquals(2, resultModel.secondModel.size());
Assertions.assertEquals("Param1.Value", resultModel.firstModel.param1);
Assertions.assertEquals("Param2.Value", resultModel.firstModel.param2);
References
https://stackoverflow.com/questions/65762857/resttemplate-multipart-form-data-response