#java #angular #spring-boot
#java #угловой #весенняя загрузка
Вопрос:
Итак, у меня есть 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)
Это Java-код, который берет книгу Excel и возвращает ее обратно в качестве ответа:
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? Я попытался установить точку останова в VS Code сразу после this.http.get и, похоже, в случаях, когда возникает проблема, она не переходит к следующей строке кода и напрямую переходит к части catchError внизу.
Также я должен отметить, что эта проблема не возникает, когда я пытаюсь выполнить это как с Spring Boot, так и с Angular, запущенными на localhost. Это происходит, когда я либо тестирую это с помощью Spring Boot, запущенной в наших средах разработки / тестирования / prod. Я знаю, некоторые из вас могут сказать, что виноват параметр среды, но я просто хочу посмотреть, заметили ли вы что-нибудь, прежде чем я сделаю этот вывод.
Я также попытался просто отправить запрос GET в виде URL с параметрами запроса для этих запросов, для возврата ответа на которые потребовалось бы больше времени, и он также возвращает время ожидания ШЛЮЗА 504.
Комментарии:
1. Вы когда-нибудь находили решение?