リクエストボディー
リクエスト本体は、次の例に示すように、Mono
や Kotlin コルーチン Deferred
など、ReactiveAdapterRegistry
によって処理される任意の非同期型からエンコードできます。
Java
Kotlin
Mono<Person> personMono = ... ;
Mono<Void> result = client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.body(personMono, Person.class)
.retrieve()
.bodyToMono(Void.class);
val personDeferred: Deferred<Person> = ...
client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.body<Person>(personDeferred)
.retrieve()
.awaitBody<Unit>()
次の例に示すように、オブジェクトのストリームをエンコードすることもできます。
Java
Kotlin
Flux<Person> personFlux = ... ;
Mono<Void> result = client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_STREAM_JSON)
.body(personFlux, Person.class)
.retrieve()
.bodyToMono(Void.class);
val people: Flow<Person> = ...
client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.body(people)
.retrieve()
.awaitBody<Unit>()
または、実際の値がある場合は、次の例に示すように、bodyValue
ショートカットメソッドを使用できます。
Java
Kotlin
Person person = ... ;
Mono<Void> result = client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(person)
.retrieve()
.bodyToMono(Void.class);
val person: Person = ...
client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(person)
.retrieve()
.awaitBody<Unit>()
フォームデータ
フォームデータを送信するには、MultiValueMap<String, String>
を本文として提供できます。コンテンツは FormHttpMessageWriter
によって application/x-www-form-urlencoded
に自動的に設定されることに注意してください。次の例は、MultiValueMap<String, String>
の使用方法を示しています。
Java
Kotlin
MultiValueMap<String, String> formData = ... ;
Mono<Void> result = client.post()
.uri("/path", id)
.bodyValue(formData)
.retrieve()
.bodyToMono(Void.class);
val formData: MultiValueMap<String, String> = ...
client.post()
.uri("/path", id)
.bodyValue(formData)
.retrieve()
.awaitBody<Unit>()
次の例に示すように、BodyInserters
を使用してインラインでフォームデータを提供することもできます。
Java
Kotlin
import static org.springframework.web.reactive.function.BodyInserters.*;
Mono<Void> result = client.post()
.uri("/path", id)
.body(fromFormData("k1", "v1").with("k2", "v2"))
.retrieve()
.bodyToMono(Void.class);
import org.springframework.web.reactive.function.BodyInserters.*
client.post()
.uri("/path", id)
.body(fromFormData("k1", "v1").with("k2", "v2"))
.retrieve()
.awaitBody<Unit>()
マルチパートデータ
マルチパートデータを送信するには、パーツのコンテンツを表す Object
インスタンスまたはパーツのコンテンツとヘッダーを表す HttpEntity
インスタンスのいずれかである MultiValueMap<String, ?>
を提供する必要があります。MultipartBodyBuilder
は、マルチパートリクエストを準備するための便利な API を提供します。次の例は、MultiValueMap<String, ?>
を作成する方法を示しています。
Java
Kotlin
MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("fieldPart", "fieldValue");
builder.part("filePart1", new FileSystemResource("...logo.png"));
builder.part("jsonPart", new Person("Jason"));
builder.part("myPart", part); // Part from a server request
MultiValueMap<String, HttpEntity<?>> parts = builder.build();
val builder = MultipartBodyBuilder().apply {
part("fieldPart", "fieldValue")
part("filePart1", FileSystemResource("...logo.png"))
part("jsonPart", Person("Jason"))
part("myPart", part) // Part from a server request
}
val parts = builder.build()
ほとんどの場合、各パーツに Content-Type
を指定する必要はありません。コンテンツ型は、シリアライズするために選択された HttpMessageWriter
に基づいて、または Resource
の場合はファイル拡張子に基づいて自動的に決定されます。必要に応じて、オーバーロードされたビルダー part
メソッドのいずれかを使用して、各パーツに使用する MediaType
を明示的に提供できます。
MultiValueMap
を準備したら、次の例に示すように、WebClient
に渡す最も簡単な方法は body
メソッドを使用することです。
Java
Kotlin
MultipartBodyBuilder builder = ...;
Mono<Void> result = client.post()
.uri("/path", id)
.body(builder.build())
.retrieve()
.bodyToMono(Void.class);
val builder: MultipartBodyBuilder = ...
client.post()
.uri("/path", id)
.body(builder.build())
.retrieve()
.awaitBody<Unit>()
MultiValueMap
に少なくとも 1 つの String
以外の値(通常のフォームデータ(つまり application/x-www-form-urlencoded
)を表す場合もある)が含まれている場合、Content-Type
を multipart/form-data
に設定する必要はありません。これは、MultipartBodyBuilder
を使用する場合に常に当てはまり、HttpEntity
ラッパーが保証されます。
MultipartBodyBuilder
の代替として、次の例に示すように、組み込みの BodyInserters
を介して、インラインスタイルのマルチパートコンテンツを提供することもできます。
Java
Kotlin
import static org.springframework.web.reactive.function.BodyInserters.*;
Mono<Void> result = client.post()
.uri("/path", id)
.body(fromMultipartData("fieldPart", "value").with("filePart", resource))
.retrieve()
.bodyToMono(Void.class);
import org.springframework.web.reactive.function.BodyInserters.*
client.post()
.uri("/path", id)
.body(fromMultipartData("fieldPart", "value").with("filePart", resource))
.retrieve()
.awaitBody<Unit>()
PartEvent
マルチパートデータを順番にストリーミングするには、PartEvent
オブジェクトを介してマルチパートコンテンツを提供できます。
フォームフィールドは
FormPartEvent::create
で作成できます。ファイルのアップロードは
FilePartEvent::create
経由で作成できます。
Flux::concat
を介してメソッドから返されたストリームを連結し、WebClient
のリクエストを作成できます。
たとえば、このサンプルは、フォームフィールドとファイルを含むマルチパートフォームを POST します。
Java
Kotlin
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);
var resource: Resource = ...
var result: Mono<String> = webClient
.post()
.uri("https://example.com")
.body(
Flux.concat(
FormPartEvent.create("field", "field value"),
FilePartEvent.create("file", resource)
)
)
.retrieve()
.bodyToMono()
サーバー側では、@RequestBody
または ServerRequest::bodyToFlux(PartEvent.class)
経由で受信した PartEvent
オブジェクトを WebClient
経由で別のサービスに中継できます。