java - 确定 org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe with Spring Boot 1.5 和 Angular 5 的原因
问题描述
所以我有一个接收 GET 请求(Spring Boot)的 API,生成一个 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 部分。
另外我需要注意的是,当我在 localhost 中同时运行 Spring Boot 和 Angular 时,不会发生此问题。当我使用在我们的 dev/test/prod 环境中运行的 Spring Boot 进行测试时,就会发生这种情况。我知道你们中的一些人可能会说环境设置是罪魁祸首,但我只是想在我得出这个结论之前看看你们是否注意到了什么。
我还尝试将 GET 请求作为带有查询参数的 URL 发出,这些请求需要更长的时间才能返回响应,并且它还返回 504 GATEWAY TIMEOUT。
解决方案
推荐阅读
- facebook - 如何使用 Marketing API 在 facebook 中创建产品集合?
- r - library(pryr) 返回一条消息。被“pryr”覆盖的注册 S3 方法:来自 print.bytes Rcpp 的方法
- flutter - 如何在本地存储/外部 Flutter 中创建文件夹?
- php - 如果 ACF 字段不存在,是否可以回显某些内容?
- ios - 如何在 NativeScript 中的标签上应用渐变
- mysql - 计算具有值的行,然后计算所有行的总数
- android - 如何在仪器测试中使用注入的依赖项
- java - 如何在 Android 中以编程方式测量 Firestore 中文档的大小?
- spring - Eureka + Zuul + Spring Cloud Config Server + HTTPS 问题
- javascript - 遍历日期范围中的月份获取第一个和最后一个日期