Package org.springframework.http.codec.multipart

# 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 one `PartEvent` 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 first `FilePartEvent` will be followed by subsequent events.

The final `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)`.

The streams returned by these static methods can be concatenated via `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:
  - `FormPartEvent`
  - `FilePartEvent`
  - `PartEventHttpMessageReader`
  - `PartEventHttpMessageWriter`

## Method Summary

Modifier and Type
Method
Description
`org.springframework.core.io.buffer.DataBuffer`
`content()`
Return the content of this event.
`HttpHeaders`
`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 the `Content-Disposition name` parameter.

## Method Details

### name

default String name()
Return the name of the event, as provided through the `Content-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

org.springframework.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.