response output stream content length

 
0
 
Java
ava
gelo86 | 09.12.2008, 23:33
Добрый вечер. У меня есть сервис каторий генерируэт пдф и записываэт его прама в OutputStream. Этот пдф будет скачан через бровзер (download). Знаю, что бивает что скачаеш пдф а открит не можеш (пишет что broken document - adobe reader). Если перед записю в OutputStream запишеш сколко занемает скачеваемый фаил, то все работает. У меня ситуация такая, что я генерирую на лету фаил дла скачки и сразу записаваю в OutputStream (если сначала в масив баитов то палучаю out of memore error). Как узнать, сколко же баитов било записано в os, после визова myServiceObject,generatePDF(os);.



public void service(HttpServletRequest req, HttpServletResponse res) [
...
OutputStream os = res.getOutputStream();
myServiceObject,generatePDF(os);
response.setContentLength( ???? )
os.flush();
os.close();
...
}

Ответы (7)
ava
necromancer | 10.12.2008, 15:34 #
1. можно увеличить размер памяти под JVM
2. можно попробовать проставить размер больший и статичный
3. можно попробовать проставить размер -1
4. можно файл писать на диск, а затем отдавать пользователю.

выставлять ContentLength необходимо перед отдачей данных в поток.
ava
COVD | 10.12.2008, 19:17 #
Наверняка вы используете стандартный веб контейнер (Томкат , например), и проблема скорее всего в том, что вы что-то лишнее делаете.

Если заранее обьем респонса не известен (как раз ваш случай), то согласно протоколу http 1.1 (определяется контейнером из запроса) контейнер будет использовать chunked режим, а в http 1.0 конец данных определяется закрытием соединения. В обоих случаях не надо использовать setContentLength (..). Также и закрывать соединение не обязательно - контейнер сам сделает.
ava
necromancer | 11.12.2008, 15:26 #
to COVD:
ну получит клиент 30кб вместо 30Мб и будет думать что все прошло отлично и сохраненный кусок полный.
ava
COVD | 11.12.2008, 17:37 #
Цитата


ну получит клиент 30кб вместо 30Мб и будет думать что все прошло отлично и сохраненный кусок полный.



так для того и протокол, чтобы не "думать".
ava
skhilkov | 12.12.2008, 10:01 #
COVD,
не соглачен ) HTTP протокол достаточно ненадежный. Если хочется проверить что до клиента дошло все как надо, то лучше проверять длину/контрольную сумму. ИМХО конечно.
ava
COVD | 12.12.2008, 16:40 #
Цитата


HTTP протокол достаточно ненадежный



Возможно, ненадежно, когда конец данных определяется разрывом соединения - соединение может быть аварийно разорвано в середине данных. Но этот способ применялся в HTTP 1.0. В версии 1.1 используется chunked - сервер отправляет данные порциями, и перед каждой порцией высылает ее размер. Вроде надежней некуда.

Если не ошибаюсь, сервлеты "заточены" под динамические данные и автоматом используют "chunked".

Не говоря о том, что новомодные технологии ajax , comet базируются на chunked.
ava
Tony | 12.12.2008, 17:04 #
Зака4ай в ByteArrayOutputStream out, потом посмотри size(), и затетм out.writeTo(servletOutputStrem)
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить