【问题标题】:Issues moving from RestTemplate to WebClient (Spring Boot 2.0.0.M3)从 RestTemplate 转移到 WebClient 的问题 (Spring Boot 2.0.0.M3)
【发布时间】:2018-01-20 12:05:55
【问题描述】:

在这个问题上被难住了一段时间!

从常规 MVC 项目迁移到响应式项目,并且正在使用 Spring Boot(新版本 2.0.0.M3)。

在出现这个特殊问题之前,我对整个库的问题为零。

在使用 WebClient 时,我有一个无法正常工作的请求。以前使用 RestTemplate 工作得很好:

rt.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
headers.add("Authorization", "Basic REDACTED");

HttpEntity<OtherApiRequest> entity = 
new HttpEntity<OtherApiRequest>(CrawlRequestBuilder.buildCrawlRequest(req), headers);

ResponseEntity<Void> response = rt.postForEntity("https://other_api/path", 
    entity, 
    Void.class);

System.out.println(response.getStatusCode());

我的 WebClient 代码:

client
  .post()
  .uri("https://other_api/path")
  .header("Authorization", "Basic REDACTED")
  .contentType(MediaType.APPLICATION_JSON)
  .body(Mono.just(req), OtherApiRequest.class)
  .exchange()
  .then(res -> System.out.println(res.getStatusCode()));

我也尝试过先生成身体:

ObjectMapper mapper = new ObjectMapper();
String body = mapper.writeValueAsString(
client
  .post()
  .uri("https://other_api/path")
  .header("Authorization", "Basic REDACTED")
  .contentType(MediaType.APPLICATION_JSON)
  .body(body, String.class)
  .exchange()
  .then(res -> System.out.println(res.getStatusCode()));

这里有什么明显的错误吗?我看不出两者之间有任何会导致第二个失败的问题...

编辑: RestTemplate 提供了 204 的响应。WebClient 提供了 400 的响应,表示正文是无效的 JSON。使用上面 WebClient 的第二个示例,我可以打印 body 变量并查看它是正确的 JSON。

Edit2:我正在序列化的 POJO 类:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class OtherApiRequest {
    private String app;
    private String urllist;
    private int maxDepth;
    private int maxUrls;

   public OtherApiRequest(String app, String urllist, int maxDepth, int maxUrls) {
        this.app = app;
        this.urllist = urllist;
        this.maxDepth = maxDepth;
        this.maxUrls = maxUrls;
    }

   public String getApp() {
        return app;
    }

   public String getUrllist() {
        return urllist;
    }

   public int getMaxDepth() {
        return maxDepth;
    }

   public int getMaxUrls() {
        return maxUrls;
    }

   public String toString() {
        return "OtherApiRequest: {" +
            "app: " + app + "," +
            "urllist: " + urllist + "," +
            "max_depth: " + maxDepth + "," +
            "max_urls: " + maxUrls +
            "}";
    }
}

【问题讨论】:

  • “不工作”是什么意思?你看到了什么行为?
  • 我的错!对于 RestTemplate 的常规响应,我得到 204,但使用 WebClient 我得到 400 响应,表示正文不是正确的 JSON。使用上面的第二个 WebClient 示例,我打印了我创建的正文,当我打印出 body 变量时,它的格式正确。我将编辑上面的请求以反映这一点。
  • 你可以试试这个:.body(BodyInserters.fromPublisher(Mono.just("data")), String.class);.body(BodyInserters.fromObject("data")); 与序列化的 json 字符串吗?
  • 这两个建议都提供相同的 400 响应和相同的消息。
  • 嗯,你能显示你设置为正文的 JSON-String 吗?

标签: spring spring-boot spring-webflux


【解决方案1】:

编辑:

在这里查看更好的答案

Missing Content-Length header sending POST request with WebClient (SpringBoot 2.0.2.RELEASE)

错误报告

https://github.com/spring-projects/spring-framework/issues/21085

在 2.2 中修复

当我遇到“无效 JSON 响应”时,我通过 netcat 查看了 WebClient 请求,发现实际负载(在此示例中为 3.16)包含在某种内容信息中:

$ netcat -l 6500
PUT /value HTTP/1.1
user-agent: ReactorNetty/0.7.5.RELEASE
transfer-encoding: chunked
host: localhost:6500
accept-encoding: gzip
Content-Type: application/json

4
3.16
0

在我将contentLength() 添加到构建器后,前面的 4 和后面的 0 消失了。

【讨论】:

    猜你喜欢
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-26
    • 2018-05-17
    • 1970-01-01
    • 2018-03-13
    • 2018-02-05
    相关资源
    最近更新 更多