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
FilePartEvents, containing the filename used when uploading. If the file is large enough to be split across multiple buffers, the firstFilePartEventwill 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,PartEvents 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.booleanisLast()Indicates whether this is the last event of a particular part.default Stringname()Return the name of the event, as provided through theContent-Disposition nameparameter.
-
Method Details
-
name
Return the name of the event, as provided through theContent-Disposition nameparameter.- Returns:
- the name of the part, never
nullor 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.
-