FormPartEvent or a FilePartEvent.
PartEvent containing both headers and a
buffer with the contents of the part.
FormPartEvent,
containing the value of the field.FilePartEvents,
containing the filename used when
uploading. If the file is large enough to be split across multiple buffers,
the first FilePartEvent 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.
PartEvents can be created to represent a file upload.
FormPartEvent#create(String, String).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);
FormPartEvent, FilePartEvent, PartEventHttpMessageReader, PartEventHttpMessageWriter
| Modifier and Type | Method and Description |
|---|---|
| public DataBuffer | |
| public HttpHeaders | |
| public boolean | |
| public default String | Returns: the name of the part, nevernull or emptyReturn the name of the event, as provided through the
|
| content | back to summary |
|---|---|
| public DataBuffer content() Return the content of this event. The returned buffer must be consumed or released. | |
| headers | back to summary |
|---|---|
| public HttpHeaders headers() Return the headers of the part that this event belongs to. | |
| isLast | back to summary |
|---|---|
| public boolean isLast() Indicates whether this is the last event of a particular part. | |
| name | back to summary |
|---|---|
| public default String name() Return the name of the event, as provided through the
| |