此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.2.0spring-doc.cadn.net.cn

请求正文

请求正文可以从ReactiveAdapterRegistry, 喜欢Mono或 Kotlin 协程Deferred如下例所示:spring-doc.cadn.net.cn

Mono<Person> personMono = ... ;

Mono<Void> result = client.post()
		.uri("/persons/{id}", id)
		.contentType(MediaType.APPLICATION_JSON)
		.body(personMono, Person.class)
		.retrieve()
		.bodyToMono(Void.class);

您还可以对对象流进行编码,如下例所示:spring-doc.cadn.net.cn

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);

或者,如果您有实际值,则可以使用bodyValue快捷方法, 如下例所示:spring-doc.cadn.net.cn

Person person = ... ;

Mono<Void> result = client.post()
		.uri("/persons/{id}", id)
		.contentType(MediaType.APPLICATION_JSON)
		.bodyValue(person)
		.retrieve()
		.bodyToMono(Void.class);

表单数据

要发送表单数据,您可以提供MultiValueMap<String, String>作为 body 进行。请注意, content 会自动设置为application/x-www-form-urlencodedFormHttpMessageWriter.以下示例演示如何使用MultiValueMap<String, String>:spring-doc.cadn.net.cn

MultiValueMap<String, String> formData = ... ;

Mono<Void> result = client.post()
		.uri("/path", id)
		.bodyValue(formData)
		.retrieve()
		.bodyToMono(Void.class);

您还可以使用BodyInserters,如下例所示:spring-doc.cadn.net.cn

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);

多部分数据

要发送多部分数据,您需要提供MultiValueMap<String, ?>其值为 也Object表示部分内容的实例或HttpEntity表示内容和 Headers 的 Headers 进行分配。MultipartBodyBuilder提供了一个方便的 API 来准备一个 multipart 请求。以下示例演示如何创建MultiValueMap<String, ?>:spring-doc.cadn.net.cn

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();

在大多数情况下,您不必指定Content-Type对于每个部分。内容 type 是根据HttpMessageWriter选择序列化它 或者,如果Resource,具体取决于文件扩展名。如有必要,您可以 显式提供MediaType用于每个部分,通过一个重载的 架构工人part方法。spring-doc.cadn.net.cn

一旦MultiValueMap已准备好,最简单的方法是将其传递给WebClient是 通过body方法,如下例所示:spring-doc.cadn.net.cn

MultipartBodyBuilder builder = ...;

Mono<Void> result = client.post()
		.uri("/path", id)
		.body(builder.build())
		.retrieve()
		.bodyToMono(Void.class);

如果MultiValueMap包含至少一个非Stringvalue 的 表示常规表单数据(即application/x-www-form-urlencoded),则无需 将Content-Typemultipart/form-data.使用MultipartBodyBuilder,这可确保HttpEntity包装纸。spring-doc.cadn.net.cn

作为MultipartBodyBuilder,您还可以提供多部分内容, inline-样式,通过内置的BodyInserters,如下例所示:spring-doc.cadn.net.cn

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);

PartEvent

要按顺序流式传输多部分数据,您可以通过以下方式提供多部分内容PartEvent对象。spring-doc.cadn.net.cn

您可以通过Flux::concat,然后为 这WebClient.spring-doc.cadn.net.cn

例如,此示例将 POST 包含表单字段和文件的多部分表单。spring-doc.cadn.net.cn

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);

在服务器端,PartEvent通过@RequestBodyServerRequest::bodyToFlux(PartEvent.class)可以中继到另一个服务 通过WebClient.spring-doc.cadn.net.cn


APP信息