Loading...
Spring Framework Reference Documentation 7.0.2의 Request Body의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
The request body는 다음 예제에서 보이는 것처럼 Mono 또는 Kotlin Coroutines Deferred와 같이
ReactiveAdapterRegistry에서 처리되는 어떤 asynchronous type으로도 인코딩될 수 있습니다:
1Mono<Person> personMono = ... ; 2 3Mono<Void> result = client.post() 4 .uri("/persons/{id}", id) 5 .contentType(MediaType.APPLICATION_JSON) 6 .body(personMono, Person.class) 7 .retrieve() 8 .bodyToMono(Void.class);
1val personDeferred: Deferred<Person> = ... 2 3client.post() 4 .uri("/persons/{id}", id) 5 .contentType(MediaType.APPLICATION_JSON) 6 .body<Person>(personDeferred) 7 .retrieve() 8 .awaitBody<Unit>()
또한 다음 예제에서 보이는 것처럼 객체의 스트림을 인코딩할 수도 있습니다:
1Flux<Person> personFlux = ... ; 2 3Mono<Void> result = client.post() 4 .uri("/persons/{id}", id) 5 .contentType(MediaType.APPLICATION_STREAM_JSON) 6 .body(personFlux, Person.class) 7 .retrieve() 8 .bodyToMono(Void.class);
1val people: Flow<Person> = ... 2 3client.post() 4 .uri("/persons/{id}", id) 5 .contentType(MediaType.APPLICATION_JSON) 6 .body(people) 7 .retrieve() 8 .awaitBody<Unit>()
또한 실제 값을 가지고 있는 경우에는, 다음 예제에서 보이는 것처럼 bodyValue shortcut 메서드를
사용할 수 있습니다:
1Person person = ... ; 2 3Mono<Void> result = client.post() 4 .uri("/persons/{id}", id) 5 .contentType(MediaType.APPLICATION_JSON) 6 .bodyValue(person) 7 .retrieve() 8 .bodyToMono(Void.class);
1val person: Person = ... 2 3client.post() 4 .uri("/persons/{id}", id) 5 .contentType(MediaType.APPLICATION_JSON) 6 .bodyValue(person) 7 .retrieve() 8 .awaitBody<Unit>()
form data를 전송하기 위해서는 body로 MultiValueMap<String, String>을 제공할 수 있습니다.
콘텐츠는 FormHttpMessageWriter에 의해 자동으로 application/x-www-form-urlencoded로
설정된다는 점에 유의해야 합니다. 다음 예제는 MultiValueMap<String, String>을 사용하는 방법을
보여줍니다:
1MultiValueMap<String, String> formData = ... ; 2 3Mono<Void> result = client.post() 4 .uri("/path", id) 5 .bodyValue(formData) 6 .retrieve() 7 .bodyToMono(Void.class);
1val formData: MultiValueMap<String, String> = ... 2 3client.post() 4 .uri("/path", id) 5 .bodyValue(formData) 6 .retrieve() 7 .awaitBody<Unit>()
또한 다음 예제에서 보이는 것처럼 BodyInserters를 사용하여 인라인으로 form data를
제공할 수도 있습니다:
1import static org.springframework.web.reactive.function.BodyInserters.*; 2 3Mono<Void> result = client.post() 4 .uri("/path", id) 5 .body(fromFormData("k1", "v1").with("k2", "v2")) 6 .retrieve() 7 .bodyToMono(Void.class);
1import org.springframework.web.reactive.function.BodyInserters.* 2 3client.post() 4 .uri("/path", id) 5 .body(fromFormData("k1", "v1").with("k2", "v2")) 6 .retrieve() 7 .awaitBody<Unit>()
multipart data를 전송하기 위해서는 값이 part 콘텐츠를 나타내는 Object 인스턴스이거나
콘텐츠와 part에 대한 헤더를 나타내는 HttpEntity 인스턴스인
MultiValueMap<String, ?>을 제공해야 합니다. MultipartBodyBuilder는 multipart 요청을
준비하기 위한 편리한 API를 제공합니다. 다음 예제는 MultiValueMap<String, ?>을 생성하는 방법을
보여줍니다:
1MultipartBodyBuilder builder = new MultipartBodyBuilder(); 2builder.part("fieldPart", "fieldValue"); 3builder.part("filePart1", new FileSystemResource("...logo.png")); 4builder.part("jsonPart", new Person("Jason")); 5builder.part("myPart", part); // Part from a server request 6 7MultiValueMap<String, HttpEntity<?>> parts = builder.build();
1val builder = MultipartBodyBuilder().apply { 2 part("fieldPart", "fieldValue") 3 part("filePart1", FileSystemResource("...logo.png")) 4 part("jsonPart", Person("Jason")) 5 part("myPart", part) // Part from a server request 6} 7 8val parts = builder.build()
대부분의 경우 각 part에 대해 Content-Type을 지정할 필요가 없습니다. 콘텐츠 타입은
이를 직렬화하기 위해 선택된 HttpMessageWriter에 따라 자동으로 결정되며,
Resource의 경우에는 파일 확장자에 따라 결정됩니다. 필요한 경우, 오버로드된
builder part 메서드 중 하나를 통해 각 part에 사용할 MediaType을 명시적으로
제공할 수 있습니다.
MultiValueMap이 준비되면, 다음 예제에서 보이는 것처럼 이를 WebClient에 전달하는
가장 쉬운 방법은 body 메서드를 사용하는 것입니다:
1MultipartBodyBuilder builder = ...; 2 3Mono<Void> result = client.post() 4 .uri("/path", id) 5 .body(builder.build()) 6 .retrieve() 7 .bodyToMono(Void.class);
1val builder: MultipartBodyBuilder = ... 2 3client.post() 4 .uri("/path", id) 5 .body(builder.build()) 6 .retrieve() 7 .awaitBody<Unit>()
MultiValueMap이 적어도 하나의 non-String 값을 포함하는 경우, 이는
일반적인 form data(application/x-www-form-urlencoded)를 나타낼 수도 있는데,
이 경우 Content-Type을 multipart/form-data로 설정할 필요가 없습니다.
이는 HttpEntity 래퍼를 보장하는 MultipartBodyBuilder를 사용할 때 항상
해당됩니다.
MultipartBodyBuilder의 대안으로, 다음 예제에서 보이는 것처럼 내장된
BodyInserters를 통해 인라인 스타일로 multipart 콘텐츠를 제공할 수도 있습니다:
1import static org.springframework.web.reactive.function.BodyInserters.*; 2 3Mono<Void> result = client.post() 4 .uri("/path", id) 5 .body(fromMultipartData("fieldPart", "value").with("filePart", resource)) 6 .retrieve() 7 .bodyToMono(Void.class);
1import org.springframework.web.reactive.function.BodyInserters.* 2 3client.post() 4 .uri("/path", id) 5 .body(fromMultipartData("fieldPart", "value").with("filePart", resource)) 6 .retrieve() 7 .awaitBody<Unit>()
PartEventmultipart data를 순차적으로 스트림하기 위해서는 PartEvent 객체를 통해 multipart 콘텐츠를
제공할 수 있습니다.
FormPartEvent::create를 통해 생성할 수 있습니다.FilePartEvent::create를 통해 생성할 수 있습니다.메서드에서 반환된 스트림은 Flux::concat을 통해 연결할 수 있으며, WebClient에 대한
요청을 생성할 수 있습니다.
예를 들어, 이 샘플은 form field와 file을 포함하는 multipart form을 POST합니다.
1Resource resource = ... 2Mono<String> result = webClient 3 .post() 4 .uri("https://example.com") 5 .body(Flux.concat( 6 FormPartEvent.create("field", "field value"), 7 FilePartEvent.create("file", resource) 8 ), PartEvent.class) 9 .retrieve() 10 .bodyToMono(String.class);
1var resource: Resource = ... 2var result: Mono<String> = webClient 3 .post() 4 .uri("https://example.com") 5 .body( 6 Flux.concat( 7 FormPartEvent.create("field", "field value"), 8 FilePartEvent.create("file", resource) 9 ) 10 ) 11 .retrieve() 12 .bodyToMono()
서버 사이드에서, @RequestBody 또는
ServerRequest::bodyToFlux(PartEvent.class)를 통해 수신된 PartEvent 객체는
WebClient를 통해 다른 서비스로 전달될 수 있습니다.
Exchange
Filters