确定org.apache.catalina.connector.ClientAbortException的原因:java.io.IOException:带有Spring Boot 1.5和Angular 5的管道损坏

时间:2019-03-27 14:41:47

标签: java angular spring-boot

所以我有一个API,可以接收GET请求(Spring Boot),生成一个excel文件,并将其返回给客户端(Angular),并且可以正常工作,但是我在前端收到504时收到了以下异常对于更大和更长生成文件的响应。

Caused by: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
     at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:393)
     at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:426)
     at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:342)

这是获取excel工作簿并将其返回作为响应的Java代码:

    public ResponseEntity<?> doReturn(ResponseDTO responseDTO, String fileName, HttpServletRequest req,
        String methodName) throws Exception {

      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

      Workbook workbook = responseDTO.getWorkbook();
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      try {
          workbook.write(out);
      } catch (IOException e) {
          throw e;
      } finally {
        try {
            workbook.close();
        } catch (IOException e) {
            logger.info("User: " + user + " failed to close exported file from " + methodName);
        }
      }

      ResponseEntity<?> resp = new ResponseEntity<>(out.toByteArray(), headers, HttpStatus.OK);
    }

以下是发出请求的Angular代码:

exportwithparam(url, fileName, Params): Observable<string> {
    let Headers = new HttpHeaders().set("Authorization", "Basic " + btoa(environment.roles.basicAuth)).set("Content-Type", "application/json");
    return this.http
    .get(url, { headers: Headers, responseType: 'arraybuffer', observe: 'response', withCredentials: true, params: Params })
    .pipe(
        map(res => {
            let errmsg = "You have successfully exported " + fileName;
            if (res.ok) {
            let blob = new Blob([res.body], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
            if (window.navigator.msSaveOrOpenBlob) {
                window.navigator.msSaveBlob(blob, fileName);
            } else {
                let objectUrl = URL.createObjectURL(blob);
                let a = document.createElement('a');
                a.href = objectUrl;
                a.target = '_blank';
                a.download = fileName;
                document.body.appendChild(a);
                a.click();
            }
        }
        return errmsg;
  }),
  catchError((err: HttpErrorResponse): string => {
    if (err.status == 504) {
      throw "Gateway Time-out";
    } else {
      let errormessage = String.fromCharCode.apply(null, new Uint8Array(err.error));
      throw errormessage;
    }
  })
  )
}

我想知道在Java代码中我做错了什么会导致此异常。但是,如果是客户端断开连接,那么Angular中有什么我可以做的吗?我试图在this.http.get之后设置VS Code中的断点,并且似乎在发生问题的情况下,它不会流到下一行代码,而直接转到底部的catchError部分。

我还要注意,当我在本地主机中运行Spring Boot和Angular时,都不会发生此问题。当我使用在我们的dev / test / prod环境中运行的Spring Boot对此进行测试时,就会发生这种情况。我知道有些人可能会说环境是罪魁祸首,但我只是想看看你们在我得出结论之前是否注意到任何事情。

我还尝试过将GET请求作为带有这些请求的查询参数的URL发出,这需要花费更长的时间才能返回响应,并且还会返回504 GATEWAY TIMEOUT。

0 个答案:

没有答案