java - Spring WebFlux,如何调试我的 WebClient POST 交换?

标签 java spring project-reactor spring-webflux

我无法理解我在构建 WebClient 请求时做错了什么。我想了解实际的 HTTP 请求是什么样的。 (例如,将原始请求转储到控制台)

POST /rest/json/send HTTP/1.1
Host: emailapi.dynect.net
Cache-Control: no-cache
Postman-Token: 93e70432-2566-7627-6e08-e2bcf8d1ffcd
Content-Type: application/x-www-form-urlencoded

apikey=ABC123XYZ&from=example%40example.com&to=customer1%40domain.com&to=customer2%40domain.com&to=customer3%40domain.com&subject=New+Sale+Coming+Friday&bodytext=You+will+love+this+sale.

我正在使用 Spring5 的响应式(Reactive)工具来构建 API。我有一个实用程序类,它将使用 Dyn 的电子邮件 API 发送电子邮件。我想使用新的 WebClient 类来完成这个(org.springframework.web.reactive.function.client.WebClient)

以下命令取自:https://help.dyn.com/email-rest-methods-api/sending-api/#postsend

curl --request POST "https://emailapi.dynect.net/rest/json/send" --data "apikey=ABC123XYZ&from=example@example.com&to=customer1@domain.com&to=customer2@domain.com&to=customer3@domain.com&subject=New Sale Coming Friday&bodytext=You will love this sale."

当我使用实际值在 curl 中进行调用时,电子邮件会正确发送,所以我觉得我生成的请求不正确。

我的发送命令

public Mono<String> send( DynEmailOptions options )
{
    WebClient webClient = WebClient.create();
    HttpHeaders headers = new HttpHeaders();
    // this line causes unsupported content type exception :(
    // headers.setContentType( MediaType.APPLICATION_FORM_URLENCODED );
    Mono<String> result = webClient.post()
        .uri( "https://emailapi.dynect.net/rest/json/send" )
        .headers( headers )
        .accept( MediaType.APPLICATION_JSON )
        .body( BodyInserters.fromObject( options ) )
        .exchange()
        .flatMap( clientResponse -> clientResponse.bodyToMono( String.class ) );
    return result;
}

我的 DynEmailOptions 类

import java.util.Collections;
import java.util.Set;

public class DynEmailOptions
{
    public String getApikey()
    {
        return apiKey_;
    }

    public Set<String> getTo()
    {
        return Collections.unmodifiableSet( to_ );
    }

    public String getFrom()
    {
        return from_;
    }

    public String getSubject()
    {
        return subject_;
    }

    public String getBodytext()
    {
        return bodytext_;
    }

    protected DynEmailOptions(
        String apiKey,
        Set<String> to,
        String from,
        String subject,
        String bodytext
    )
    {
        apiKey_ = apiKey;
        to_ = to;
        from_ = from;
        subject_ = subject;
        bodytext_ = bodytext;
    }

    private Set<String> to_;
    private String from_;
    private String subject_;
    private String bodytext_;
    private String apiKey_;
}

最佳答案

您当前正尝试“按原样”序列化请求正文,而不使用正确的 BodyInserter .

在这种情况下,我认为你应该把你的 DynEmailOptions对象变成 MultiValueMap<String, String>然后:

MultiValueMap<String, String> formData = ...
Mono<String> result = webClient.post()
                .uri( "https://emailapi.dynect.net/rest/json/send" )
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .accept( MediaType.APPLICATION_JSON )
                .body( BodyInserters.fromFormData(formData))
                .retrieve().bodyToMono(String.class);

关于java - Spring WebFlux,如何调试我的 WebClient POST 交换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45986417/

相关文章:

Java libgdx 创建和显示秒表

spring - 路径变量 spring Restful 服务中的 URL

java - 使用 reactor 的 Flux.buffer 进行批处理仅适用于单个项目

java - Eclipse和Mysql连接错误

java - batik :Linux 上的 svg 到 pdf(无 X 服务器)

java - 覆盖 JSTL 中的变量

java - OSGI 环境中的 Spring 应用程序

java - 将 @Id Marshall 转换为 JSON,同时保留 Java 8 时间格式

spring - 我们如何将 Mono<List<Type>> 转换为 Flux<Type>

java - .switchIfEmpty() 急切地求值有什么意义?