所以我有一个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。