1. 概述

在这个教程中,我们将学习如何使用Feign客户端发送带有表单URL编码数据的POST API请求。

2. 发送POST表单URL编码数据的方法

有两种不同的方式可以发送POST表单URL编码数据。首先,我们需要创建一个自定义编码器并将其配置到我们的Feign客户端:

class FormFeignEncoderConfig {
    @Bean
    public Encoder encoder(ObjectFactory<HttpMessageConverters> converters) {
        return new SpringFormEncoder(new SpringEncoder(converters));
    }
}

我们将在Feign客户端配置中使用这个自定义类:

@FeignClient(name = "form-client", url = "http://localhost:8085/api",
  configuration = FormFeignEncoderConfig.class)
public interface FormClient {
    // request methods
}

现在,Feign和bean配置已完成。接下来,我们将研究请求方法。

2.1. 使用POJO(面向对象)

我们将创建一个Java POJO类,其中包含所有表单参数作为成员:

public class FormData {
    int id;
    String name;
    // constructors, getters and setters
}

在POST请求中,我们将把这个对象作为请求体传递。

@PostMapping(value = "/form", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
void postFormData(@RequestBody FormData data);

让我们验证我们的代码:请求体应该包含"id"和"name"作为表单URL编码数据:

@Test
public void givenFormData_whenPostFormDataCalled_thenReturnSuccess() {
    FormData formData = new FormData(1, "baeldung");
    stubFor(WireMock.post(urlEqualTo("/api/form"))
      .willReturn(aResponse().withStatus(HttpStatus.OK.value())));

    formClient.postFormData(formData);
    wireMockServer.verify(postRequestedFor(urlPathEqualTo("/api/form"))
      .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded; charset=UTF-8"))
      .withRequestBody(equalTo("name=baeldung&id=1")));
}

2.2. 使用Map

我们也可以使用Map而不是POJO类,在POST请求体中发送表单URL编码数据。

@PostMapping(value = "/form/map", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
void postFormMapData(Map<String, ?> data);

注意,Map的值应该是'?'。

验证我们的代码:

@Test
public void givenFormMap_whenPostFormMapDataCalled_thenReturnSuccess() {
    Map<String, String> mapData = new HashMap<>();
    mapData.put("name", "baeldung");
    mapData.put("id", "1");
    stubFor(WireMock.post(urlEqualTo("/api/form/map"))
      .willReturn(aResponse().withStatus(HttpStatus.OK.value())));

    formClient.postFormMapData(mapData);
    wireMockServer.verify(postRequestedFor(urlPathEqualTo("/api/form/map"))
      .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded; charset=UTF-8"))
      .withRequestBody(equalTo("name=baeldung&id=1")));
}

3. 总结

在这篇文章中,我们了解了如何在请求体中使用表单URL编码数据发送POST API请求。

如往常一样,示例的完整源代码可在GitHub上找到。