接口 PartEvent
- 所有已知子接口:
FilePartEvent,FormPartEvent
- 所有已知实现类:
DefaultPartEvents.AbstractPartEvent,DefaultPartEvents.DefaultFilePartEvent,DefaultPartEvents.DefaultFormFieldPartEvent,DefaultPartEvents.DefaultPartEvent
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 content of the part.
- Form field 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 filename = fileEvent.filename();
Flux<DataBuffer> contents = partEvents.map(PartEvent::content);
// handle file upload
}
else {
return Mono.error("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(
FormEventPart.create("field", "field value"),
FilePartEvent.create("file", resource)
), PartEvent.class)
.retrieve()
.bodyToMono(String.class);
- 从以下版本开始:
- 4.0 2022/4/22 9:10
- 作者:
- Arjen Poutsma, Harry Yang
- 另请参阅:
-
方法概要
修饰符和类型方法说明cn.taketoday.core.io.buffer.DataBuffercontent()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.
-
方法详细资料
-
name
Return the name of the event, as provided through theContent-Disposition nameparameter.- 返回:
- the name of the part, never
nullor empty
-
headers
HttpHeaders headers()Return the headers of the part that this event belongs to. -
content
cn.taketoday.core.io.buffer.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.
-