Это правильный механизм?
По сути, это механизм only , предоставляемый Servlet APIs
.Вы должны сконструировать свой сервлет с учетом этого.
(Трудно понять, как это можно сделать любым другим способом. Системный вызов read
считывает данные в память с устройства(диск). Системный вызов write
записывает данные из памяти на устройство (сетевой интерфейс). Системного вызова для передачи данных непосредственно с одного устройства на другое не существует. Лучшее, что вы можете сделать, - это уменьшить объем копированияданные в приложении . Если вы используете что-то вроде IOUtils.copy
, это должно сводить это к минимуму, насколько это возможно. Единственный способ избежать использования памяти приложения - это использовать какое-то специальное оборудование / операционную системуКомбинация оптимизирована для доставки контента.)
Однако, в любом случае, это, вероятно, спорный вопрос.В большинстве случаев узким местом в производительности может быть перемещение данных по сети.Вероятно, данные могут быть прочитаны с диска в память, скопированы и записаны в сетевой интерфейс на порядки быстрее, чем они могут перемещаться по сети в веб-браузер пользователя (или что-либо еще).
Если это НЕ спорныйтогда практическим способом доставки контента будет использование отдельного веб-сервера, реализованного в собственном коде, который мы оптимизировали для доставки статического контента;например, что-то вроде nginx
.)
Что, если я решу не отправлять файл в конце обработки Servlet
?Например: если я скопировал InputStream
в OutputStream
, а затем выяснил, что это не авторизованный запрос, и пользователь не имеет права видеть этот объект (возможно, ошибка в дизайне), я все равно отправил бы некоторые данные клиенту, хотя это не то, что я намеревался или нет.
Вы должны написать свой сервлет для проверки доступа ПЕРЕД чтением содержимого в память.И в идеале, перед тем как «зафиксировать» ответ, отправив заголовок ответа.