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...