2013-04-18 2 views
1

Я работаю над приложением, работающим на JBoss5.1, JEE5, JSF2, Spring3.0, Icefaces2.0, HTML и Jquery1.8.

У меня есть требование генерации файлов «на лету» для загрузки клиентов. Когда создается файл, в настоящее время я передаю содержимое файла в виде байтов на страницу JSF и используя <ice:outputResource>, чтобы показать ссылку для загрузки. Это отлично подходит для файлов меньшего размера. По мере увеличения размера файла это не является хорошим решением, так как я столкнулся с проблемами OutOfMemoryError, потому что приложение JVM должно нести нагрузку на перенос содержимого файла в кучу, а затем воронку через приложение.

Что я хотел бы сделать, так это предоставить сгенерированные файлы в виде прямых ссылок, чтобы они могли обслуживаться сетью, содержащейся в HTTP. У меня есть ограничение сделать это в безопасной среде, чтобы пользователь был аутентифицирован, прежде чем он сможет создать и увидеть ссылку. Таким образом, я планирую сгенерировать файл в каталог WEB-INF и удалить файл, как только пользователь загрузит, что фактически делает WEB-INF содержащим только файлы, которые в настоящее время просматриваются клиентами. Я не уверен , как сервер JBoss обрабатывает эти файлы с точки зрения кеширования и влияет на производительность сервера. Кроме того, я ценю, есть ли альтернативные подходы к моей проблеме.Эффективный способ публикации сгенерированных файлов на сервере?

Я считаю, что я четко описал свою проблему, если не сообщите мне. Заранее благодарим за ваше время и помощь.

PS - Я даже могу создавать файлы за пределами WEB-INF и все еще сделать их безопасными.

+1

вы не должны генерировать файлы в WEB-INF, вы должны использовать системный каталог temp (или какой-либо настроенный рабочий каталог для вашего приложения). – jtahlborn

+0

В зависимости от того, как вы создаете файлы, вам даже не нужны временные файлы, вы можете передать их прямо клиенту. – jtahlborn

+0

@jtahlborn Спасибо, да, все в порядке. Я даже могу создать вне WEB-INF и все еще сделать их безопасными. Я создаю файлы в CSV, PDF и XLS, используя Java FileOutputStream. Когда вы говорите поток прямо к клиенту, можете ли вы подробно рассказать? – IndoKnight

ответ

2
  • используйте некоторую предварительно сконфигурированную папку вне вашего webapp на сервере. Как уже упоминалось ранее в комментариях, не рекомендуется создавать их внутри WEB-INF
  • создать сервлет, который будет обслуживать содержимое запрашиваемого файла пользователю из вашей предварительно сконфигурированной папки
  • вы также можете защитить сервлет, если это необходимо
  • сервлет может также удалить файл, как только он был доставлен пользователю
  • в качестве альтернативы, вы можете map external folder в веб-приложение, и пусть JBoss служить им в качестве статического контента (но вам нужно защитить доступ, если это необходимо)

Постскриптум вы все равно можете выполнить некоторую «запланированную» очистку, если сгенерированный файл никогда не загружается.

Servlet обслуживающий содержание (Ответ на ваш комментарий)

Я не вижу никаких проблем с безопасностью при наличии внешней папки в вашем случае. Эта внешняя папка доступна только в вашем приложении.

Предположим, у вас есть каталог, в котором вы создаете файлы (FilesRootDir) -/var/myapp/storage/tmp.

  1. Создание сервлета в вашем веб-приложение, которое знает местоположение вашего FilesRootDir
  2. Скажем сервлета отображается на следующий адрес (/ mywebapp/загрузка/файл)
  3. Для простоты вашего сервлет получает в качестве параметра относительного пути к файлу (генерируемой пути)
  4. Принимая выше
    1. приложение генерирует файл здесь/вар/MyApp/с torage/TMP/dir1/document.csv
    2. и генерирует ссылку /mywebapp/downloads/file?path=/dir1/document.csv, так что пользователь может загрузить файл
  5. Когда пользователь решает загрузите файл, запрос обрабатывается вашим сервлетом.
    1. сервлет получает местоположение запрашиваемого файла - /dir1/document.csv
    2. создает абсолютный путь конкатенации FilesRootDir и параметр пути - /вар/MyApp/хранение/TMP/dir1/документ .csv
    3. Читает и выводит содержимое файла пользователю

Я считаю, вы можете обратиться т те же ограничения безопасности для вашего сервлета, как и у вас в вашем приложении, потому что это часть приложения.

+0

Спасибо за ваш ответ. Я не хочу создавать вне своего webapp, потому что, если мне нужно перезаписать код аутентификации перед тем, как обслуживать файл. Как именно вы предлагаете Servlet для обслуживания содержимого файла? Кроме того, могу ли я использовать аутентификацию приложения для обслуживания статических внешних файлов с использованием конфигурации JBoss? +1 для вашей информации о функции сервера приложений JBoss. – IndoKnight

+2

@ И наконец-то увидишь ансперто комментарий в «главном ответе» –

+0

Спасибо, я попробую этот подход. – IndoKnight

0

Подавать содержание, но использовать длинный хэш для открытых файлов подвергаясь на сервере, например, для файла image.jpg, использовать URL как этот:

http://yourserver.com/somepath/bNKq9Ro_UZeesmQlVs9OQkrKVlpxzpzPXf9DCTbqe_FbLczI 

Сохранить хэш bNKq9Ro_UZeesmQlVs9OQkrKVlpxzpzPXf9DCTbqe_FbLczI в базе данных и связать его с файлом image.jpg, другими словами:

hashfunction('image.jpg') = 'bNKq9Ro_UZeesmQlVs9OQkrKVlpxzpzPXf9DCTbqe_FbLczI 

Понадобится компьютер около 3 TRESVIGINTILLION ЛЕТ угадать хэш файла, как это.