У меня есть обработчик при развертывании сервера причала, который имеет ссылку на объект HttpServletResponse.Установка длины содержимого в объекте ответа HTTP после записи в его OutputStream
Я пишу содержание байт в Response.getOutputStream(), как показано ниже:
ServletOutputStream serlvetOutputStream = handlerContext.getResponse().getOutputStream();
...
while(condition) {
//read chunk from some source into byteBuffer
servletOutputStream.write(byteBuffer, 0, lengthRead);
}
Но перед тем я могу писать записи(), я должен установить Content-Length клиент HTTP ожидает в ответ:
handlerContext.getResponse().setContentLength((int) length); //or as below
handlerContext.getResponse().addHeader("Content-Length", String.valueOf(length));
Неспособность установить длину перед записью в OutputStream, приводит к «Ошибка размера файла неизвестно» во всплывающем окне на клиентском приложении Windows. Но в некоторых случаях я не знаю, какова будет длина, которая будет написана до тех пор, пока она не появится. Я не могу накапливать все данные, которые нужно прочитать заранее (потому что он может тайм-аут клиента для больших данных), поэтому он должен быть «chunked», то есть читать x килобайт, а затем писать x килобайт, пока условие не станет ложным.
Мой вопрос: есть ли способ динамически обновлять длину контента непосредственно перед записью? В вышеприведенном цикле я хочу установить длину содержимого, как если бы многие байты были доступны для записи, записи(), а затем обновляли его снова, когда он перемещался.
Если я обновляю длину содержимого в цикле, я получаю jetty.server.EoFexception.
Если вы читаете данные chunked, и вы не можете буферизовать все данные на Java, то вы не можете узнать фактическую сумму, прочитанную. Есть ли вероятность, что вы могли бы оценить длину контента, или API, из которого вы читаете, дает некоторую оценку? –
Как следует из названия, Content-Length является заголовком и может устанавливаться один раз только в начале вашего ответа. В зависимости от происхождения ваших данных (файл, blob и т. Д.), Посмотрите, есть ли у вас метаданные, из которых вы можете запросить ожидаемую длину перед потоковой передачей содержимого. В противном случае вам может потребоваться буфер для всего потока (в памяти или на диске), определить его длину и затем установить заголовок и запустить ответ. Наконец, если длина контента по-настоящему невозможно определить вверх, посмотрите на обновление клиента и посмотрите на HTTP-потоки или потоковые протоколы. –
Заголовки могут быть отправлены только до фактического содержимого, так работает HTTP. –