У меня есть следующий сценарий:
- GET-ресурс из удаленного бэкэнда, HttpResponse backendResponse содержит ответ от удаленного бэкэнда.
- Ресурс сжат как GZIP.
- Я распаковываю HttpEntity с помощью GzipDecompressingEntity.
- Я копирую GZIPInputStream в ServletOutputStream (я получаю его из ответа HttpServletResponse) и отправляю обратно скопированный поток (ServletOutputStream) клиенту.
На последнем шаге я получаю следующее исключение EOFException:
Caused by: java.io.EOFException: null
at java.util.zip.GZIPInputStream.readUByte(GZIPInputStream.java:264)
at java.util.zip.GZIPInputStream.readUShort(GZIPInputStream.java:254)
at java.util.zip.GZIPInputStream.readUInt(GZIPInputStream.java:246)
at java.util.zip.GZIPInputStream.readTrailer(GZIPInputStream.java:218)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:118)
at java.io.FilterInputStream.read(FilterInputStream.java:114)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1792)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1769)
Это большая часть моего кода:
private HttpServletResponse response;
private HttpResponse backendResponse;
private void copyResponseToClient() throws IOException {
HttpEntity entity = backendResponse.getEntity();
if (entity != null) {
entity = new GzipDecompressingEntity(entity);
copyResponseEntity(entity.getContent());
}
}
private static void copyResponseEntity(final GZIPInputStream in) throws IOException {
try {
IOUtils.copyLarge(in, response.getOutputStream());
} finally {
IOUtils.closeQuietly(in);
}
}
Некоторые вещи, которые нужно запомнить:
- Запросом к удаленному бэкэнду является Content Encoding как gzip.
- Этот код является специфическим для этого сценария.
- Когда я использую команду GzipDecompressingEntity.getContentLength (), я получаю-1 (это жестко запрограммировано в getContentLength), так как CopyLarge знает, пока не скопировать?
- Я получаю EOFException в readTrailer, потому что gziФайл p искажен?