如何使用 WebClient 反应式 Web 客户端发送带有 zip 正文的 POST 请求 [英] How can I send POST request with zip body using WebClient reactive web client
问题描述
如何使用 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.runAllTasks(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();BodyInserter
如果我在命令行上执行以下 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/资产包)是问题所在.请帮助...
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...
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屋!