Interface PartEvent
- All Known Subinterfaces:
FilePartEvent
,FormPartEvent
public interface PartEvent
Represents an event for a "multipart/form-data" request.
Can be a
FormPartEvent
or a FilePartEvent
.
Server Side
Each part in a multipart HTTP message produces at least onePartEvent
containing both headers
and a
buffer with the contents of the part.
- Form fields will produce a single
FormPartEvent
, containing the value of the field. - File uploads will produce one or more
FilePartEvent
s, containing the filename used when uploading. If the file is large enough to be split across multiple buffers, the firstFilePartEvent
will be followed by subsequent events.
PartEvent
for a particular part will have
isLast()
set to true
, and can be followed by
additional events belonging to subsequent parts.
The isLast()
property is suitable as a predicate for the
Flux.windowUntil(Predicate)
operator, in order to split events from
all parts into windows that each belong to a single part.
From that, the Flux.switchOnFirst(BiFunction)
operator allows you to
see whether you are handling a form field or file upload.
For example:
Flux<PartEvent> allPartsEvents = ... // obtained via @RequestPayload or request.bodyToFlux(PartEvent.class) allPartsEvents.windowUntil(PartEvent::isLast) .concatMap(p -> p.switchOnFirst((signal, partEvents) -> { if (signal.hasValue()) { PartEvent event = signal.get(); if (event instanceof FormPartEvent formEvent) { String value = formEvent.value(); // handle form field } else if (event instanceof FilePartEvent fileEvent) { String filename = fileEvent.filename(); Flux<DataBuffer> contents = partEvents.map(PartEvent::content); // handle file upload } else { return Mono.error(new RuntimeException("Unexpected event: " + event)); } } else { return partEvents; // either complete or error signal } }))Received part events can also be relayed to another service by using the
WebClient
.
See below.
NOTE that the body contents must be completely consumed, relayed, or released to avoid memory leaks.
Client Side
On the client side,PartEvent
s can be created to represent a file upload.
- Form fields can be created via
FormPartEvent.create(String, String)
. - File uploads can be created via
FilePartEvent.create(String, Path)
.
Flux.concat(Publisher[])
to create a request for the
WebClient
:
For instance, this sample will POST a multipart form containing a form field
and a file.
Resource resource = ... Mono<String> result = webClient .post() .uri("https://example.com") .body(Flux.concat( FormPartEvent.create("field", "field value"), FilePartEvent.create("file", resource) ), PartEvent.class) .retrieve() .bodyToMono(String.class);
- Since:
- 6.0
- Author:
- Arjen Poutsma
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptioncontent()
Return the content of this event.headers()
Return the headers of the part that this event belongs to.boolean
isLast()
Indicates whether this is the last event of a particular part.default String
name()
Return the name of the event, as provided through theContent-Disposition name
parameter.
-
Method Details
-
name
Return the name of the event, as provided through theContent-Disposition name
parameter.- Returns:
- the name of the part, never
null
or empty
-
headers
HttpHeaders headers()Return the headers of the part that this event belongs to. -
content
DataBuffer content()Return the content of this event. The returned buffer must be consumed or released. -
isLast
boolean isLast()Indicates whether this is the last event of a particular part.
-