使用StreamingResponseBody使用RestTemplate调用另一个微服务Api

时间:2019-11-15 15:40:03

标签: java rest spring-boot post microservices

我在使用spring-boot进行这次休息时遇到一些问题

在第一个微服务中称为API,用于创建我的PDF

@PostMapping(value = PdfMakerPathConstants.ENDPOINT_PDF_TYPE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<StreamingResponseBody> createPdf(@PathVariable(PdfMakerPathConstants.PDF_TYPE) String type,
        @RequestBody Map<String, Object> params) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_PDF);
    String filename = params.containsKey(PdfMakerPathConstants.FILENAME)
            ? params.get(PdfMakerPathConstants.FILENAME).toString()
            : type;
    headers.setContentDisposition(ContentDisposition.builder("attachment").filename(filename + ".pdf").build());

    headers.setAccessControlExposeHeaders(Arrays.asList("Content-Disposition"));

    return ResponseEntity.ok().headers(headers).body(os -> pdfGen.createPdf(type, params, os));
}

这是客户端类,用于调用PDF-API

public ResponseEntity<StreamingResponseBody> createPdf(Map<String, Object> params) {
        String urlCreazione = System.getProperty(ATENA_PDFMAKER_URL);

        RequestCallback requestCallback = request -> {
            HttpHeaders headers = request.getHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_PDF));

            jsonMapper.writeValue(request.getBody(), params);
        };

        ResponseExtractor<ResponseEntity<StreamingResponseBody>> responseExtractor = response -> {

            StreamingResponseBody responseBody = outputStream -> {
                try (InputStream body = response.getBody()) {
                    StreamUtils.copy(body, outputStream);
                }
            };
            return new ResponseEntity<>(responseBody, response.getHeaders(), response.getStatusCode());
        };

        return restTemplate.execute(urlCreazione, HttpMethod.POST, requestCallback, responseExtractor);
    }

我有这个异常。我需要Async TaskExecutor或类似的东西吗?第一次我有这种问题。

我有疑问,因为我不明白为什么流会关闭(我附加了调试图像)

Debug

Please, configure a TaskExecutor in the MVC config under "async support".
The SimpleAsyncTaskExecutor currently in use is not suitable under load.
-------------------------------
Request URI: '/stations/525591/config-historycal-components/2019-08-05T15:31:08'
!!!
2019-11-15 10:08:38.173|ERROR||||||org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]:175|Servlet.service() for servlet [dispatcherServlet] threw exception
java.io.IOException: stream is closed
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.ensureOpen(HttpURLConnection.java:3423)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3448)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3443)
    at org.springframework.util.StreamUtils.copy(StreamUtils.java:142)
    at it.enel.atena.web.client.PdfClient.lambda$null$1(PdfClient.java:47)
    at org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:97)
    at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:327)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.lang.Thread.run(Thread.java:748)
2019-11-15 10:08:38.176|ERROR||||||org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]:175|Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.io.IOException: stream is closed
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.ensureOpen(HttpURLConnection.java:3423)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3448)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3443)
    at org.springframework.util.StreamUtils.copy(StreamUtils.java:142)
    at it.enel.atena.web.client.PdfClient.lambda$null$1(PdfClient.java:47)
    at org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:97)
    at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:327)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.lang.Thread.run(Thread.java:748)
2019-11-15 10:08:38.310|WARN ||||||org.apache.catalina.core.AsyncContextImpl:175|onError() call failed for listener of type [org.apache.catalina.core.AsyncListenerWrapper]
java.lang.IllegalArgumentException: Cannot dispatch without an AsyncContext
    at org.springframework.util.Assert.notNull(Assert.java:198)
    at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.dispatch(StandardServletAsyncWebRequest.java:130)
    at org.springframework.web.context.request.async.WebAsyncManager.setConcurrentResultAndDispatch(WebAsyncManager.java:390)
    at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$2(WebAsyncManager.java:314)
    at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.lambda$onError$0(StandardServletAsyncWebRequest.java:145)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.onError(StandardServletAsyncWebRequest.java:145)
    at org.apache.catalina.core.AsyncListenerWrapper.fireOnError(AsyncListenerWrapper.java:49)
    at org.apache.catalina.core.AsyncContextImpl.setErrorState(AsyncContextImpl.java:410)
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:239)
    at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:241)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
2019-11-15 10:08:42.643|INFO |||printComponentsHistorycalConfig|CPX-1CRYTMEQ2CQ|0:0:0:0:0:0:0:1|it.enel.atena.web.utility.WebUtilities:37|WebUtilities.initLogInfos - informazioni log correttamente inizializzate
2019-11-15 10:08:42.644|INFO |||printComponentsHistorycalConfig|CPX-1CRYTMEQ2CQ|0:0:0:0:0:0:0:1|it.enel.atena.web.rest.controller.impianto.StationsPrintController:36|StationsPrintController.printComponentsHistorycalConfig - idStation: 525591
2019-11-15 10:09:16.153|INFO |||printComponentsHistorycalConfig|CPX-1CRYTMEQ2CQ|0:0:0:0:0:0:0:1|it.enel.atena.web.rest.controller.impianto.StationsPrintController:51|StationsPrintController.printComponentsHistorycalConfig - FINE
2019-11-15 10:09:16.174|ERROR||||||org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]:175|Servlet.service() for servlet [dispatcherServlet] threw exception
java.io.IOException: stream is closed
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.ensureOpen(HttpURLConnection.java:3423)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3448)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3443)
    at org.springframework.util.StreamUtils.copy(StreamUtils.java:142)
    at it.enel.atena.web.client.PdfClient.lambda$null$1(PdfClient.java:47)
    at org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:97)
    at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:327)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.lang.Thread.run(Thread.java:748)
2019-11-15 10:09:16.176|ERROR||||||org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]:175|Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.io.IOException: stream is closed
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.ensureOpen(HttpURLConnection.java:3423)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3448)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3443)
    at org.springframework.util.StreamUtils.copy(StreamUtils.java:142)
    at it.enel.atena.web.client.PdfClient.lambda$null$1(PdfClient.java:47)
    at org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:97)
    at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:327)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.lang.Thread.run(Thread.java:748)
2019-11-15 10:09:16.185|WARN ||||||org.apache.catalina.core.AsyncContextImpl:175|onError() call failed for listener of type [org.apache.catalina.core.AsyncListenerWrapper]
java.lang.IllegalArgumentException: Cannot dispatch without an AsyncContext
    at org.springframework.util.Assert.notNull(Assert.java:198)
    at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.dispatch(StandardServletAsyncWebRequest.java:130)
    at org.springframework.web.context.request.async.WebAsyncManager.setConcurrentResultAndDispatch(WebAsyncManager.java:390)
    at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$2(WebAsyncManager.java:314)
    at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.lambda$onError$0(StandardServletAsyncWebRequest.java:145)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.onError(StandardServletAsyncWebRequest.java:145)
    at org.apache.catalina.core.AsyncListenerWrapper.fireOnError(AsyncListenerWrapper.java:49)
    at org.apache.catalina.core.AsyncContextImpl.setErrorState(AsyncContextImpl.java:410)
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:239)
    at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:241)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

0 个答案:

没有答案