| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Хранение ресурсов web-приложения в jar'e |
| Автор: Maksym 11.2.2007, 12:09 |
| Собственно, сабж. Хочется запаковать все ресурсы web-приложения в jar и положить этот jar в dependencies нескольких проектов с одинаковой идеей интерфейса. Подскажите, пожалуйста, можно ли в jsp сослаться на css или изображение, спрятанное в jar'e, и если можно то как? ЗЫ. Используется ли такая практика? или, может быть, есть другие приемы хранения и предоставления в web-интерфейсы общих ресурсов? |
| Автор: MisterCleric 12.2.2007, 13:09 |
| Собственно можно. Как универсально сделать не подскажу. Но покажу пример. Я использую webwork. В его jar'e запакован FCKeditor он лежит по таком пути: webwork-2.2.2.jar\com\opensymphony\webwork\static\richtexteditor\ на странице к его js & css обращаюсь так: <script language="JavaScript" type="text/javascript" src="<%=request.getContextPath()%>/webwork/richtexteditor/fckeditor.js"></script> Как я понимаю путь ищеться от: <filter> <filter-name>webwork</filter-name> <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class> </filter> В общем и все. Других вариантов не пробовал. И как-то мысли даже не было. Пробуй |
| Автор: Maksym 12.2.2007, 14:16 |
| MisterCleric Большое спасибо. Формат не очень нравится (<%=request.getContextPath()%>/webwork/richtexteditor/fckeditor.js>), но конечно попробую. All Нет ли еще идей? (честно говоря я рассчитывал на прямой путь, заложенный в технологию, а не на трюк) |
| Автор: Stampede 12.2.2007, 15:49 |
| Maksym, идея как бы понятна: распространять модуль в виде бинарника, в котором уже запакованы все элементы его вебного интерфейса. Подтыкнул к проекту - и сразу пользуйся. Может, и не лишено смысла. Реализовать тоже можно, и даже не особенно трудно. Щас раскажу как. Мне видятся два пути. Оба связаны с написанием кастомного сервлета. 1. Сервлет, выдающий содержимое архива. Напишем сервлет, который, скажем, по адресу "/archive/yourfile.jar/img/button.gif" понимает, что нужно пойти в стандартную папку WEB-INF/lib, найти там yourfile.jar, открыть его как архив, прочитать содержимое файла img/button.gif и выдать его в поток вывода. 2. Сервлет, выдающий ресурсы Здесь предлагается написать сервлет, который использует метод Class.getResourceAsStream(String path). Опять-таки, надо продумать шаблон пути, который будет однозначно мапиться на даный сервлет, и часть которого будет указывать на путь внутри архива. Для все того же файла кнопки в yourfile.jar УРЛ мог бы выглядеть так: "/resources/img/buton.gif". Теперь сравним варианты. Второй быстрее в реализации, поскольку поиск и разрешение пути к ресурсу за тебя сделает система, используя стандартный механизм лукапа загрузчиками классов. Кроме того, УРЛ'ы при этом получаются компактными, и в них не надо явно прописывать имя архива. С другой стороны, первый сервлет может быть более универсальным, так как теоретически мы могли бы запрограммировать его таким образом, чтобы он доставал нам статику из любого архива, который мы укажем - и не обязательно лежащего на classpath. А уж как это указать - это целиком дело фантазии разработчиков. Можно задавать через параметры инициализации сервлета, можно через собственную конфигурацию, можно через часть УРЛ, а можно все вместе. Так что дерзай. Интересно будет услышать, что и как получается. |
| Автор: Maksym 12.2.2007, 17:20 |
| Stampede Спасибо. Первый вариант кажется более интересным с точки зрения масштабируемости и реиспользования. Удивляет отсутствие готовых решений. |
| Автор: Maksym 19.2.2007, 17:59 | ||||||
Выкроил время и написал коротенькое решение. Работает. Прошу о code-review.
В пакет test.framework.ui.resources.img кладутся все общие изображения, в test.framework.ui.resources.css -- общие стили и т.п. Все это запаковывается в framework.jar (в Eclipse удобно создать для этих целей Utility Project и подключать его к зависимым приложениям), который подключается в j2ee dependencies тех web-приложений, которые будут использовать эти ресурсы. В web.xml этих приложений не забываем указать:
И после этого в проектах запросто можно пользоваться общими ресурсам:
|
| Автор: Tony 19.2.2007, 18:34 | ||
A ещё можно 4ерз NIO. |
| Автор: Maksym 19.2.2007, 18:50 |
| Tony Спасибо. С буфером, конечно, будет быстрее. А что даст использование nio? Добавлено @ 18:51 Размер буфера 4096 чем подсказан? исходя из чего его стоит вычислять? |
| Автор: Tony 19.2.2007, 20:43 | ||||
NIO (new IO) побыстрее работает с input/output, чем класси4еская модель in/out.
Зависит от коли4ества запросов к ресурсу. Если мало запросов и маленкие файлики(цсс,иконки...) то можно сразу весь файл загрузить в массив и выдать его, не исползуя for (как в примере выше). Нас4ёт NIO.(вариант 2)
|
| Автор: Maksym 19.2.2007, 22:34 |
| Tony Apache IO API предлагает сделать все вызовом одного метода -- http://jakarta.apache.org/commons/io/api-release/org/apache/commons/io/IOUtils.html (вариант 3) Какой способ эффективнее? Все таки речь идет о многократно повторяющейся операции |
| Автор: Tony 19.2.2007, 23:42 |
| Да знаю 4то есть у Jakarti. Если ты хо4ешь ложить либу ради одного метода флаг в руки. Нас4ёт производительности надо сорсы смотреть. Сорри нету времени(завтра). |
| Автор: Maksym 24.2.2007, 16:58 | ||
| Tony Исходник org.apache.commons.io.IOUtils.copy(InputStream input, OutputStream output):
Разницы с твоим вариантом для io, кажется, нет. Дополнительно вычисляется никому не нужный count (the number of bytes copied) и все. All Не работал с nio. Действительно ли его предпочтительнее изпользовать в подобных ситуациях? В чем заключается его оптимизация по сравнению со стандартной моделью? |
| Автор: Tony 24.2.2007, 20:45 | ||
Полно имфы (и на русском языке). http://www.javable.com/javaworld/04_03/01/ |
| Автор: Maksym 20.3.2007, 20:55 | ||
Окончательный вариант (на данный момент). Используется в серии проектов с большим количеством общих ресурсов. Пока проблем не было.
Размер буфера параметризуется в зависимости от приложения. Для логирования используется внешний класс UILogger (helper для использования log4j). Интересно, что реалзиация через nio не заработала... Код молча отработал и в response все ушло, но к пользователю ничего не попало... |
| Автор: Tony 22.3.2007, 17:41 | ||
Вот это интерсно |
| Автор: Maksym 22.3.2007, 19:59 |
| Tony Есть ли InputStream'ы, с которыми nio работать не может? Например, если они порождаются налету внутри jvm и никак средствами операционной системы к ним не достучаться.. |
| Автор: Maksym 18.4.2007, 00:26 | ||
| По ходу использования тема получила свое логическое продолжение. Теперь наш сервлет не только отдает common ресурсы из .jar, но и: - пакует их gzip для браузеров, поддерживающих компрессию - устанавливает expiration date, last modified, content length в response В результате значительно уменшилось количество IOException'ов выпадающих из этого сервлета в лог, похоже это связано с тем, что браузеры запрашивают ресурсы меньшее количество раз, а если запрашивают то точно знают объем данных которых нужно дождаться (кроме того сам объем данных уменьшился за счет компрессии).
|
| Автор: Stampede 18.4.2007, 01:07 |
| Отлично, Maksym - держи плюса! Не совсем понятна несогласованная логика выставления Expires и max-age (через месяц безостановочной работы сервера все ресурсы будут отдаваться как уже "испарившиеся"), но да ладно. Все равно полезная вещь, а подправить под себя всегда можно при желании. |