Spring Web Reactive | 2. WebClient | 2.4. Request Body
요청 본문은 다음 예와 같이 Mono
나 Kotlin 코루틴(Coroutines) Deferred
등 ReactiveAdapterRegistry
에 의해 처리되는 모든 비동기 유형에서 인코딩 할 수 있다.
Java
Mono<Person> personMono = ... ;
Mono<Void> result = client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.body(personMono, Person.class)
.retrieve()
.bodyToMono(Void.class);
Kotlin
val personDeferred: Deferred<Person> = ...
client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.body<Person>(personDeferred)
.retrieve()
.awaitBody<Unit>()
다음의 예와 같이 객체 스트림을 인코딩 할 수 있다.
Java
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);
Kotlin
val people: Flow<Person> = ...
client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.body(people)
.retrieve()
.awaitBody<Unit>()
또는 실제 값이 있는 경우는 다음의 예와 같이, 간단히 bodyValue
메소드를 사용할 수 있다.
Java
Person person = ... ;
Mono<Void> result = client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(person)
.retrieve()
.bodyToMono(Void.class);
Kotlin
val person: Person = ...
client.post()
.uri("/persons/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(person)
.retrieve()
.awaitBody<Unit>()
2.4.1. 폼 데이터(Form Data)
폼 데이터를 전송하려면 MultiValueMap<String, String>
을 본문으로 제공 할 수 있다. 콘텐츠는 FormHttpMessageWriter
에 의해 application/x-www-form-urlencoded
으로 자동 설정되는 것에 주의해라. 다음 예제는 MultiValueMap<String, String>
사용 방법을 보여준다.
Java
MultiValueMap<String, String> formData = ... ;
Mono<Void> result = client.post()
.uri("/path", id)
.bodyValue(formData)
.retrieve()
.bodyToMono(Void.class);
Kotlin
val formData: MultiValueMap<String, String> = ...
client.post()
.uri("/path", id)
.bodyValue(formData)
.retrieve()
.awaitBody<Unit>()
다음의 예와 같이, BodyInserters
을 사용하여 인라인 폼 데이터를 제공 할 수 있다.
Java
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);
Kotlin
import org.springframework.web.reactive.function.BodyInserters.*
client.post()
.uri("/path", id)
.body(fromFormData("k1", "v1").with("k2", "v2"))
.retrieve()
.awaitBody<Unit>()
2.4.2. 멀티파트 데이터(Multipart Data)
멀티파트 데이터를 전송하려면, 파트 콘텐츠(part content)를 나타내는 Object 인스턴스 또는 파트 컨텐츠와 헤더를 나타내는 HttpEntity
인스턴스 중 하나인 MultiValueMap<String, ?>
를 제공해야 한다. MultipartBodyBuilder
는 멀티 파트 요청을 준비하기 위한 편리한 API를 제공한다. 다음의 예는 MultiValueMap<String, ?>
을 만드는 방법을 보여준다.
Java
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();
Kotlin
val builder = MultipartBodyBuilder().apply {
part("fieldPart", "fieldValue")
part("filePart1", new FileSystemResource("...logo.png"))
part("jsonPart", new Person("Jason"))
part("myPart", part) // Part from a server request
}
val parts = builder.build()
대부분의 경우는 각 파트의 Content-Type
를 지정할 필요가 없다. 콘텐츠 형식은 직렬화하기 위해 선택된 HttpMessageWriter
에 따라 또는 Resource
의 경우 파일 확장자에 따라 자동으로 결정된다. 필요에 따라 오버로드 된 빌더 part
메소드 중 하나를 사용하여 각 부품에 사용 MediaType
을 명시적으로 제공 할 수 있다.
MultiValueMap
가 준비되면 다음의 예와 같이, WebClient
에 전달하는 가장 쉬운 방법은 body
메소드를 사용하는 것이다.
Java
MultipartBodyBuilder builder = ...;
Mono<Void> result = client.post()
.uri("/path", id)
.body(builder.build())
.retrieve()
.bodyToMono(Void.class);
Kotlin
val builder: MultipartBodyBuilder = ...
client.post()
.uri("/path", id)
.body(builder.build())
.retrieve()
.awaitBody<Unit>()
MultiValueMap
에 적어도 하나의 String 다른 값(보통 폼 데이터. 즉, application/x-www-form-urlencoded
를 나타내는 경우도 있다)가 포함되어 있는 경우, Content-Type
를 multipart/form-data
로 설정할 필요는 없다. 이것은 MultipartBodyBuilder
을 사용하는 경우 항상 적용, HttpEntity 래퍼가 보장된다.
MultipartBodyBuilder
의 대안으로 다음의 예와 같이 내장의 BodyInserters
를 통해 인라인 스타일의 멀티 파트 콘텐츠를 제공 할 수 있다.
Java
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);
Kotlin
import org.springframework.web.reactive.function.BodyInserters.*
client.post()
.uri("/path", id)
.body(fromMultipartData("fieldPart", "value").with("filePart", resource))
.retrieve()
.awaitBody<Unit>()