如何使用WebClient反应式Web客户端发送带有zip正文的POST请求

时间:2019-02-01 22:23:25

标签: java spring-boot

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

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

调试代码时,出现以下错误: 池连接发现错误

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
            }

如果我在命令行上执行以下CURL,则会得到结果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

应将其翻译成Java反应性代码。问题是PDFReactor的请求正文(邮编/资产包)。请帮助...

PDFReactor

1 个答案:

答案 0 :(得分:0)

  

PDF的内容类型为MediaType.APPLICATION_PDF

如下所示更改内容类型

ERROR Unexpected error detected in bolt session '8c8590fffeb2c45f-000098a4-00000004-54a89d3a07b39611-ca025a5c'. Failed to process a bolt message
org.neo4j.bolt.v1.runtime.BoltConnectionFatality: Failed to process a bolt message
    at org.neo4j.bolt.v1.runtime.BoltStateMachine.handleFailure(BoltStateMachine.java:742)
    at org.neo4j.bolt.v1.runtime.BoltStateMachine.handleFailure(BoltStateMachine.java:728)
    at org.neo4j.bolt.v1.runtime.BoltStateMachine.access$500(BoltStateMachine.java:62)
    at org.neo4j.bolt.v1.runtime.BoltStateMachine$State$1.init(BoltStateMachine.java:435)
    at org.neo4j.bolt.v1.runtime.BoltStateMachine.init(BoltStateMachine.java:145)
    at org.neo4j.bolt.v1.messaging.BoltMessageRouter.lambda$onInit$0(BoltMessageRouter.java:70)
    at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatch(DefaultBoltConnection.java:195)
    at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatch(DefaultBoltConnection.java:143)
    at org.neo4j.bolt.runtime.ExecutorBoltScheduler.executeBatch(ExecutorBoltScheduler.java:170)
    at org.neo4j.bolt.runtime.ExecutorBoltScheduler.lambda$scheduleBatchOrHandleError$2(ExecutorBoltScheduler.java:153)
    at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.neo4j.bolt.security.auth.AuthenticationException: The client is unauthorized due to authentication failure.
    at org.neo4j.bolt.security.auth.BasicAuthentication.doAuthenticate(BasicAuthentication.java:78)
    at org.neo4j.bolt.security.auth.BasicAuthentication.authenticate(BasicAuthentication.java:60)
    at org.neo4j.bolt.v1.runtime.BoltStateMachineSPI.authenticate(BoltStateMachineSPI.java:93)
    at org.neo4j.bolt.v1.runtime.BoltStateMachine$State$1.init(BoltStateMachine.java:412)
    ... 10 more
2019-02-02 02:31:53.511+0000 INFO  starting batching from `UNWIND $ingredientUpcModels as node return node` operation using iteration `MERGE (src:Token {name: node.tokenKey})  ON CREATE SET src.name = node.tokenKey, src.creationDate = {processDate},  src.updateDate = {processDate} MERGE (dest:Item {divUpc: node.divUpc})  ON CREATE SET dest.upc = node.upc,    dest.divNumber = node.division,    dest.divUpc = node.divUpc,    dest.creationDate = {processDate} MERGE (src)-[r:TOKEN_ITEM]->(dest)  ON CREATE SET r.creationDate = {processDate}  SET r.score = node.score, r.updateDate = {processDate} )` in separate thread
2019-02-02 02:31:53.544+0000 WARN  Error during iterate.commit:
2019-02-02 02:31:53.544+0000 WARN  1 times: org.neo4j.graphdb.TransactionFailureException: Transaction was marked as successful, but unable to commit transaction so rolled back.
2019-02-02 02:31:53.545+0000 WARN  Error during iterate.execute:
2019-02-02 02:31:53.545+0000 WARN  1 times: Invalid input ')': expected whitespace, comment, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',', LOAD CSV, FROM, INTO, START, MATCH, UNWIND, MERGE, CREATE GRAPH >>, CREATE >> GRAPH, CREATE GRAPH, CREATE, SET, DELETE GRAPHS, DELETE, REMOVE, FOREACH, WITH, CALL, PERSIST, RELOCATE, RETURN, SNAPSHOT, UNION, ';' or end of input (line 1, column 515 (offset: 514))
"UNWIND {_batch} AS _batch WITH _batch.node AS node  MERGE (src:Token {name: node.tokenKey})  ON CREATE SET src.name = node.tokenKey, src.creationDate = {processDate},  src.updateDate = {processDate} MERGE (dest:Item {divUpc: node.divUpc})  ON CREATE SET dest.upc = node.upc,    dest.divNumber = node.division,    dest.divUpc = node.divUpc,    dest.creationDate = {processDate} MERGE (src)-[r:TOKEN_ITEM]->(dest)  ON CREATE SET r.creationDate = {processDate}  SET r.score = node.score, r.updateDate = {processDate} )"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   ^
2019-02-02 02:31:53.741+0000 INFO  starting batching from `UNWIND $ingredientUpcModels as node return node` operation using iteration `MERGE (src:Token {name: node.tokenKey})  ON CREATE SET src.name = node.tokenKey, src.creationDate = {processDate},  src.updateDate = {processDate} MERGE (dest:Item {divUpc: node.divUpc})  ON CREATE SET dest.upc = node.upc,    dest.divNumber = node.division,    dest.divUpc = node.divUpc,    dest.creationDate = {processDate} MERGE (src)-[r:TOKEN_ITEM]->(dest)  ON CREATE SET r.creationDate = {processDate}  SET r.score = node.score, r.updateDate = {processDate} )` in separate thread
2019-02-02 02:31:53.752+0000 WARN  Error during iterate.commit:
2019-02-02 02:31:53.752+0000 WARN  1 times: org.neo4j.graphdb.TransactionFailureException: Transaction was marked as successful, but unable to commit transaction so rolled back.
2019-02-02 02:31:53.752+0000 WARN  Error during iterate.execute:
2019-02-02 02:31:53.752+0000 WARN  1 times: Invalid input ')': expected whitespace, comment, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',', LOAD CSV, FROM, INTO, START, MATCH, UNWIND, MERGE, CREATE GRAPH >>, CREATE >> GRAPH, CREATE GRAPH, CREATE, SET, DELETE GRAPHS, DELETE, REMOVE, FOREACH, WITH, CALL, PERSIST, RELOCATE, RETURN, SNAPSHOT, UNION, ';' or end of input (line 1, column 515 (offset: 514))
"UNWIND {_batch} AS _batch WITH _batch.node AS node  MERGE (src:Token {name: node.tokenKey})  ON CREATE SET src.name = node.tokenKey, src.creationDate = {processDate},  src.updateDate = {processDate} MERGE (dest:Item {divUpc: node.divUpc})  ON CREATE SET dest.upc = node.upc,    dest.divNumber = node.division,    dest.divUpc = node.divUpc,    dest.creationDate = {processDate} MERGE (src)-[r:TOKEN_ITEM]->(dest)  ON CREATE SET r.creationDate = {processDate}  SET r.score = node.score, r.updateDate = {processDate} )"