当前位置: 首页 > 知识库问答 >
问题:

缺少使用WebClient发送POST请求的内容长度标头(SpringBoot 2.0.2.RELEASE)

潘弘扬
2023-03-14

我使用WebClient(SpringBoot 2.0.2.RELEASE)发送带有SOAP请求的帖子,但它缺少遗留API所需的“内容长度”头。

是否可以将WebClient配置为包含“内容长度”标题?SpringBoot 2.0.1中为EncoderHttpMessageWriter解决并引入了一个Spring框架问题,但它似乎不适用于JAXB。

我试着使用车身插入器

webClient.post().body(BodyInserters.fromObject(request)).exchange();

syncBody

webClient.post().syncBody(request).exchange();

他们都没有为WebClient工作。不过,当使用restemplate时,就会设置内容长度,API会成功响应

共有3个答案

谭炎彬
2023-03-14

WebClient是一个流客户端,在流完成之前很难设置内容长度。到那时,标题早就不见了。如果您使用遗留版本,您可以重用单声道(单声道/通量可以重用,Java流不能重用)并检查长度。

    public void post() {

    Mono<String> mono = Mono.just("HELLO WORLDZ");

    final String response = WebClient.create("http://httpbin.org")
            .post()
            .uri("/post")
            .header(HttpHeaders.CONTENT_LENGTH,
                    mono.map(s -> String.valueOf(s.getBytes(StandardCharsets.UTF_8).length)).block())
            .body(BodyInserters.fromPublisher(mono, String.class))
            .retrieve()
            .bodyToMono(String.class)
            .block();

    System.out.println(response);

}

一个同事(干得好Max!)我想出了更干净的解决方案,我添加了一些包装代码,以便可以测试:

    Mono<String> my = Mono.just("HELLO WORLDZZ")
            .flatMap(body -> WebClient.create("http://httpbin.org")
                    .post()
                    .uri("/post")
                    .header(HttpHeaders.CONTENT_LENGTH,
                            String.valueOf(body.getBytes(StandardCharsets.UTF_8).length))
                    .syncBody(body)
                    .retrieve()
                    .bodyToMono(String.class));

    System.out.println(my.block());
姬捷
2023-03-14

如果你像我们一样应用斯文的同事(Max)解决方案,你也可以将其应用于像你的身体是定制obj这样的情况,但你必须将其序列化一次:

String req = objectMapper.writeValueAsString(requestObject)

然后把它传给了

webClient.syncBody(req)

请记住,使用SpringBoot 2.0.3。释放,如果您将一个字符串作为请求传递给webClient,它将作为ContentType标头MediaType。TEXT_PLAIN,这使得我们与其他服务的集成失败。我们通过如下设置特定的内容类型头来解决这个问题:

httpHeaders.setContentType(MediaType.APPLICATION_JSON);
章海
2023-03-14

我也在努力解决同样的问题,因为我正在手动序列化请求(在我的例子中是JSON)并设置长度(Kotlin代码):

open class PostRetrieverWith411ErrorFix(
    private val objectMapper: ObjectMapper
) {

protected fun <T : Any> post(webClient: WebClient, body: Any, responseClass: Class<T>): Mono<T> {
    val bodyJson = objectMapper.writeValueAsString(body)

    return webClient.post()
        .contentType(MediaType.APPLICATION_JSON_UTF8)
        .contentLength(bodyJson.toByteArray(Charset.forName("UTF-8")).size.toLong())
        .syncBody(bodyJson)
        .retrieve()
        .bodyToMono(responseClass)
    }
}
 类似资料:
  • 我正在使用Spring WebClient和Spring Boot 2.3.5.Release向需要application/x-www-form-urlencoded内容类型的站点发布请求。它总是失败,因为没有设置Content-Length头。我可以在代码中设置,但我不确定当内容类型为application/x-www-form-urlencoded时如何计算内容长度。我正在访问的URL是一个遗

  • 我的HTTP头有问题。我需要发送一个带有空正文和标题“content-length:0”的post-request。但这似乎是不可能的,因为我有一个例外: --org.apache.http.ProtocolException:内容长度头已存在-- 编辑: 用@Beno Arakelyan的答案解决了这个问题。

  • 我正在努力构建两个asp.netmvc web应用程序之间的安全集成;和调用网络扫描应用程序的ERP系统。所以目前在接收器应用程序(网络扫描应用程序)上我有以下操作方法,应该只由ERP系统执行:- 而在调用者系统(ERP系统)上,我有以下调用上述动作方法的动作方法。 如上面代码所示,我正在发送一个安全令牌,它存储在两个应用程序的web中。配置文件。通过这种方式,我可以确保(或者这是我的意图)网络扫

  • 我试图计算http post请求的请求体的内容长度,但我不断得到错误,表明内容长度错误。请求正文如下所示: 我尝试了两种解决方案,比如将正文的内容连接成一个字符串,比如following,然后将其转换成字节数组并发送其长度,但没有成功。 帖子请求正文是x-wow-form-urlencoded格式,内容长度必须正确计算。任何帮助都很感激,谢谢。

  • 我想向我的节点添加文档。js API,为此,我有一个YAML文件,我把我的定义放在那里,swagger文档位于localhost:5000/API doc,运行良好。 现在,我必须用以下定义添加Bear authorization but Swagger: 在测试请求时(我点击右上角的“授权”按钮并输入我的令牌),我得到以下错误: “错误”:“未找到授权标头”。 为什么请求中不包括标题?

  • 我试图使用WebClient(spring web 5.2.9.RELEASE)发送POST多部分请求,但它缺少API所需的“内容长度”头。 是否可以将WebClient配置为包含MultipartTTpMessageWriter的“Content Length”头,该头用于使用multipart/form数据媒体类型写入请求? 我以这种方式发送请求: