如何使用 WebClient 反应式 Web 客户端发送带有 zip 正文的 POST 请求 [英] How can I send POST request with zip body using WebClient reactive web client

查看:33
本文介绍了如何使用 WebClient 反应式 Web 客户端发送带有 zip 正文的 POST 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用 WebClient 反应式 Web 客户端发布带有 ZIP(压缩数据)主体的请求.

我在内存中创建了一个 zip (bytearrayoutputstream),并希望使用 WebClient 反应式 Web 客户端在 POST 请求正文中发送 zip 数据.REST API 是一个 PdfReactor REST WebService.响应是二进制数据 (pdf).

当我调试我的代码时,我收到以下错误:池连接观察到错误

org.springframework.web.reactive.function.UnsupportedMediaTypeException:bodyType=java.io.ByteArrayInputStream 不支持内容类型application/octet-stream"在 org.springframework.web.reactive.function.BodyInserters.unsupportedError(BodyInserters.java:297) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]在 org.springframework.web.reactive.function.BodyInserters.lambda$writeWithMessageWriters$9(BodyInserters.java:287) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]在 java.base/java.util.Optional.orElseGet(Optional.java:358) ~[na:na]在 org.springframework.web.reactive.function.BodyInserters.writeWithMessageWriters(BodyInserters.java:287) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]在 org.springframework.web.reactive.function.BodyInserters.lambda$fromObject$1(BodyInserters.java:85) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]在 org.springframework.web.reactive.function.client.DefaultClientRequestBuilder$BodyInserterRequest.writeTo(DefaultClientRequestBuilder.java:257) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]在 org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$exchange$1(ExchangeFunctions.java:103) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]在 org.springframework.http.client.reactive.ReactorClientHttpConnector.lambda$connect$2(ReactorClientHttpConnector.java:110) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]在 reactor.netty.http.client.HttpClientConnect$HttpClientHandler.requestWithBody(HttpClientConnect.java:528) ~[reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]在 reactor.netty.http.client.HttpClientConnect$HttpObserver.lambda$onStateChange$0(HttpClientConnect.java:396) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]在 reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44) ~[reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE]在 reactor.core.publisher.MonoOnAssembly.subscribe(MonoOnAssembly.java:76) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE]在 reactor.netty.http.client.HttpClientConnect$HttpObserver.onStateChange(HttpClientConnect.java:397) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]在 reactor.netty.resources.PooledConnectionProvider$DisposableAcquire.onStateChange(PooledConnectionProvider.java:501) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]在 reactor.netty.resources.PooledConnectionProvider$DisposableAcquire.run(PooledConnectionProvider.java:531) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]在 io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-common-4.1.29.Final.jar:4.1.29.Final]在 io.netty.util.concurrent.SingleThreadEventExecutor.runAllTask​​s(SingleThreadEventExecutor.java:404) [netty-common-4.1.29.Final.jar:4.1.29.Final]在 io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:446) [netty-transport-4.1.29.Final.jar:4.1.29.Final]在 io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [netty-common-4.1.29.Final.jar:4.1.29.Final]在 java.base/java.lang.Thread.run(Thread.java:844) [na:na]抑制:reactor.core.publisher.FluxOnAssembly$OnAssemblyException:|_ Mono.error ⇢ org.springframework.web.reactive.function.BodyInserters.lambda$writeWithMessageWriters$9(BodyInserters.java:287)|_ Mono.defer ⇢ reactor.netty.http.client.HttpClientConnect$HttpObserver.onStateChange(HttpClientConnect.java:396)

 configuration.json:{"文档": "test.html",添加书签":真,添加链接":true}测试.html:<img src="img/image.png"/><div>您好,您好,您是 Testdokument von <span th:text="${userName}"/>.

</html>

map.put(template, tempBytesArray);map.put(配置,configByteArray);试试 (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {尝试 (ZipOutputStream zos_ = 新 ZipOutputStream(bos)) {map.forEach((k, v) -> {var zipentry = new ZipEntry(k);试试{zos_.putNextEntry(zipentry);zos_.write(v);zos_.closeEntry();} catch (IOException e) {e.printStackTrace();}});byte[] b = bos.toByteArray();BodyInserterbodyInserter = BodyInserters.fromObject(bos);byteArray = pdfReactorClient.post().uri(pdfReactorUrl + PDF_REACTOR_URL_SUFFIX).accept(MediaType.APPLICATION_OCTET_STREAM).body(BodyInserters.fromObject(bos).交换().flatMap(response -> response.bodyToMono (ByteArrayResource.class)).map(ByteArrayResource::getByteArray).block();zos_.close();} 捕获(异常 e){//TODO: 处理异常}

如果我在命令行上执行以下 CURL,我会得到结果 pdf:

curl -X POST -H "Cache-Control: no-cache" -H "Content-Type: application/zip" --data-binary @test.gzip "http://localhost:8080/服务/休息/转换.pdf" >结果.pdf.

Java 反应式代码中也应翻译相同.PDFReactor 的请求正文(Zip/资产包)是问题所在.请帮助...

PDFReactor

解决方案

PDF 的内容类型为 MediaType.APPLICATION_PDF

更改内容类型如下图

 pdfReactorClient.post().uri(pdfReactorUrl + PDF_REACTOR_URL_SUFFIX).accept(MediaType.APPLICATION_PDF)

How to POST a request with ZIP (compressed data) body using WebClient reactive web Client.

I created a zip in memory (bytearrayoutputstream) and want to send the zip data in a POST request body using WebClient reactive web Client. The REST API is a PdfReactor REST WebService. The Response is a binary data (pdf).

When I debug my Code I get the following error: Pooled connection observed an error

org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/octet-stream' not supported for bodyType=java.io.ByteArrayInputStream
    at org.springframework.web.reactive.function.BodyInserters.unsupportedError(BodyInserters.java:297) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.reactive.function.BodyInserters.lambda$writeWithMessageWriters$9(BodyInserters.java:287) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at java.base/java.util.Optional.orElseGet(Optional.java:358) ~[na:na]
    at org.springframework.web.reactive.function.BodyInserters.writeWithMessageWriters(BodyInserters.java:287) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.reactive.function.BodyInserters.lambda$fromObject$1(BodyInserters.java:85) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.reactive.function.client.DefaultClientRequestBuilder$BodyInserterRequest.writeTo(DefaultClientRequestBuilder.java:257) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$exchange$1(ExchangeFunctions.java:103) ~[spring-webflux-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.http.client.reactive.ReactorClientHttpConnector.lambda$connect$2(ReactorClientHttpConnector.java:110) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at reactor.netty.http.client.HttpClientConnect$HttpClientHandler.requestWithBody(HttpClientConnect.java:528) ~[reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]
    at reactor.netty.http.client.HttpClientConnect$HttpObserver.lambda$onStateChange$0(HttpClientConnect.java:396) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44) ~[reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE]
    at reactor.core.publisher.MonoOnAssembly.subscribe(MonoOnAssembly.java:76) [reactor-core-3.2.2.RELEASE.jar:3.2.2.RELEASE]
    at reactor.netty.http.client.HttpClientConnect$HttpObserver.onStateChange(HttpClientConnect.java:397) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]
    at reactor.netty.resources.PooledConnectionProvider$DisposableAcquire.onStateChange(PooledConnectionProvider.java:501) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]
    at reactor.netty.resources.PooledConnectionProvider$DisposableAcquire.run(PooledConnectionProvider.java:531) [reactor-netty-0.8.2.RELEASE.jar:0.8.2.RELEASE]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-common-4.1.29.Final.jar:4.1.29.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) [netty-common-4.1.29.Final.jar:4.1.29.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:446) [netty-transport-4.1.29.Final.jar:4.1.29.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [netty-common-4.1.29.Final.jar:4.1.29.Final]
    at java.base/java.lang.Thread.run(Thread.java:844) [na:na]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
    |_  Mono.error ⇢ org.springframework.web.reactive.function.BodyInserters.lambda$writeWithMessageWriters$9(BodyInserters.java:287)
    |_  Mono.defer ⇢ reactor.netty.http.client.HttpClientConnect$HttpObserver.onStateChange(HttpClientConnect.java:396)

 configuration.json:
    {
    "document": "test.html",
    "addBookmarks": true,
    "addLinks": true
    }

 test.html:
    <html>
     <img src="img/image.png" />
     <div>
    Hallo, hier ist ein Testdokument von <span th:text="${userName}" />.
     </div>
    </html>

map.put(template, tempBytesArray);
map.put(configuration, configByteArray);

        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            try (ZipOutputStream zos_ = new ZipOutputStream(bos)) {
                map.forEach((k, v) -> {
                    var zipentry = new ZipEntry(k);
                    try {
                        zos_.putNextEntry(zipentry);
                        zos_.write(v);
                        zos_.closeEntry();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
               byte[] b = bos.toByteArray();
               BodyInserter<Object, ReactiveHttpOutputMessage>     bodyInserter = BodyInserters.fromObject(bos);
               byteArray = pdfReactorClient
                        .post()
                        .uri(pdfReactorUrl + PDF_REACTOR_URL_SUFFIX)
                        .accept(MediaType.APPLICATION_OCTET_STREAM)
                        .body(BodyInserters.fromObject(bos)
                        .exchange()
                        .flatMap(response -> response.bodyToMono (ByteArrayResource.class))
                        .map(ByteArrayResource::getByteArray)
                        .block();
                zos_.close();
            } catch (Exception e) {
                // TODO: handle exception
            }

If I execute the following CURL on command line, I get the result pdf:

curl -X POST -H "Cache-Control: no-cache" -H "Content-Type: application/zip" --data-binary @test.gzip "http://localhost:8080/service/rest/convert.pdf" > result.pdf.

Same should be translated in Java reactive Code. The request body (Zip/asset package) to the PDFReactor is the problem. Kindly help please...

PDFReactor

解决方案

Content-Type for PDF is MediaType.APPLICATION_PDF

change the content type as shown below

                    pdfReactorClient
                        .post()
                        .uri(pdfReactorUrl + PDF_REACTOR_URL_SUFFIX)
                        .accept(MediaType.APPLICATION_PDF)

这篇关于如何使用 WebClient 反应式 Web 客户端发送带有 zip 正文的 POST 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆