Для чего используется WEB-INF в веб-приложении Java EE?

177

Я работаю над веб-приложением Java EE со следующей структурой исходного кода:

src/main/java                 <-- multiple packages containing java classes
src/test/java                 <-- multiple packages containing JUnit tests
src/main/resources            <-- includes properties files for textual messages
src/main/webapp/resources     <-- includes CSS, images and all Javascript files
src/main/webapp/WEB-INF
src/main/webapp/WEB-INF/tags
src/main/webapp/WEB-INF/views

Меня интересует то, что в WEB-INFнем содержатся web.xmlфайлы XML для настройки сервлетов, контексты проводки Spring bean, а также теги и представления JSP.

Я пытаюсь понять, что ограничивает / определяет эту структуру. Например, файлы JSP всегда должны быть внутри WEB-INFили они могут быть где-то еще? И есть ли что-нибудь еще, что может войти WEB-INF? В записи Wikipedia о файлах WAR упоминаются classesклассы Java и libфайлы JAR - не уверен, что я полностью понял, когда они понадобятся в дополнение к другим расположениям исходных файлов.

Стив Чемберс
источник
1
Это может быть полезно: gordondickens.com/wordpress/2012/07/03/…
smwikipedia
1
К вашему сведению… Чтобы узнать о том, как контейнеры сервлетов загружаются из WEB-INFдругих мест, см. Вопрос « Контроль пути к классам в сервлете» , особенно этот ответ .
Василий Бурк

Ответы:

216

В спецификации Servlet 2.4 говорится об WEB-INF (стр. 70):

В каталоге приложения существует специальный каталог с именем WEB-INF. Этот каталог содержит все вещи, связанные с приложением, которые не находятся в корневом каталоге документа приложения. Узел не является частью дерева документа публичного заявления . Контейнер не может напрямую передавать клиенту файл, содержащийся в каталоге. Тем не менее, содержимое каталога открыты для кода сервлета , используя и вызовы методов на , и могут быть подвержены использованием вызовов.WEB-INFWEB-INFWEB-INFgetResourcegetResourceAsStreamServletContextRequestDispatcher

Это означает, что WEB-INFресурсы доступны загрузчику ресурсов вашего веб-приложения и не доступны для общего доступа.

Вот почему многие проекты помещают свои ресурсы, такие как файлы JSP, JAR / библиотеки и свои собственные файлы классов или файлы свойств или любую другую конфиденциальную информацию в WEB-INFпапку. В противном случае они будут доступны с помощью простого статического URL (например, для загрузки CSS или Javascript).

Ваши файлы JSP могут быть где угодно, хотя с технической точки зрения. Например, в Spring вы можете настроить их WEB-INFявно:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:prefix="/WEB-INF/jsp/" 
    p:suffix=".jsp" >
</bean>

В WEB-INF/classesи WEB-INF/libпапки , указанные в Википедии WAR файлы статье приведены примеры папок , необходимых в спецификации Servlet во время выполнения.

Важно сделать различие между структурой проекта и структурой результирующего файла WAR.

Структура проекта в некоторых случаях будет частично отражать структуру файла WAR (для статических ресурсов, таких как файлы JSP или файлы HTML и JavaScript, но это не всегда так).

Переход от структуры проекта к результирующему файлу WAR выполняется процессом сборки.

В то время как вы, как правило, можете свободно разрабатывать собственный процесс сборки, в настоящее время большинство людей будут использовать стандартизированный подход, такой как Apache Maven . Среди прочего Maven определяет значения по умолчанию, для которых ресурсы в структуре проекта соответствуют каким ресурсам в результирующем артефакте (в данном случае результирующим артефактом является файл WAR). В некоторых случаях отображение состоит из простого процесса копирования, в других случаях процесс отображения включает в себя преобразование, такое как фильтрация или компиляция и другие.

Один пример : WEB-INF/classesпозже папка будет содержать все скомпилированные java-классы и ресурсы ( src/main/javaи src/main/resources), которые должны быть загружены Classloader для запуска приложения.

Другой пример : WEB-INF/libпозже папка будет содержать все файлы JAR, необходимые для приложения. В проекте maven для вас управляются зависимости, и maven автоматически копирует необходимые jar-файлы в WEB-INF/libпапку для вас. Это объясняет, почему у вас нет libпапки в проекте Maven.

mwhs
источник
2
Изменение в Servlet 3.0 и 3.1 ( JSR 340 ) позволяет обслуживать статические ресурсы и JSP из JAR-файла, хранящегося в WEB-INF / lib. Цитируя раздел 10.5 спецификации Servlet 3.1: За исключением статических ресурсов и JSP, упакованных в META-INF / resources файла JAR, который находится в каталоге WEB-INF / lib, никакие другие файлы, содержащиеся в каталоге WEB-INF, не могут быть доставляется непосредственно клиенту контейнером. Таким образом, исключение применяется только к: WAR> WEB-INF> lib> JARфайл>resources
Бэзил Бурк
1
Упс, из моего комментария выше, изменения , что последнее предложение: статические файлы могут обслуживаться из: WARфайл> WEB-INF> lib> JARфайл> META-INF> resources> yourStaticFilesGoHere .
Василий Бурк
@mwhs Я предлагаю вам пересмотреть свой ответ с новым разделом Servlet 3 и пометить текущее содержимое как раздел Servlet 2.
Василий Бурк
61

При развертывании веб-приложения Java EE (с использованием каркасов или без него) его структура должна соответствовать некоторым требованиям / спецификациям. Эти спецификации происходят из:

  • Контейнер сервлетов (например, Tomcat)
  • API сервлетов Java
  • Ваш домен приложения
  1. Требования к сервлет-серверу
    Если вы используете Apache Tomcat, корневой каталог вашего приложения должен быть помещен в папку webapp. Это может отличаться, если вы используете другой контейнер сервлета или сервер приложений.

  2. Требования API Java Servlet API
    Java Servlet утверждает, что корневой каталог приложения должен иметь следующую структуру:

    ApplicationName
    |
    |--META-INF
    |--WEB-INF
          |_web.xml       <-- Here is the configuration file of your web app(where you define servlets, filters, listeners...)
          |_classes       <--Here goes all the classes of your webapp, following the package structure you defined. Only 
          |_lib           <--Here goes all the libraries (jars) your application need

Эти требования определены Java Servlet API.

3. Область вашего приложения
Теперь, когда вы выполнили требования контейнера сервлета (или сервера приложений) и требования API сервлета Java, вы можете организовать другие части вашего веб-приложения в зависимости от того, что вам нужно.
- Вы можете поместить свои ресурсы (файлы JSP, текстовые файлы, файлы сценариев) в корневой каталог приложения. Но тогда люди могут получить к ним доступ прямо из браузера, вместо того чтобы обрабатывать их запросы с помощью некоторой логики, предоставляемой вашим приложением. Таким образом, чтобы предотвратить прямой доступ к вашим ресурсам, вы можете поместить их в каталог WEB-INF, содержимое которого доступно только для сервера.
-Если вы используете некоторые фреймворки, они часто используют файлы конфигурации. Большинство из этих фреймворков (Struts, Spring, Hibernate) требуют, чтобы вы поместили их файлы конфигурации в classpath (каталог "classes").

Патрик Б.
источник
12

Вы должны поместить в WEB-INF любые страницы или части страниц, которые вы не хотите публиковать. Обычно JSP или лицевые стороны находятся вне WEB-INF, но в этом случае они легко доступны для любого пользователя. Если у вас есть какие-либо ограничения авторизации, для этого можно использовать WEB-INF.

WEB-INF / lib может содержать сторонние библиотеки, которые вы не хотите упаковывать на системном уровне (JAR могут быть доступны для всех приложений, работающих на вашем сервере), но только для этого конкретного приложения.

Вообще говоря, многие файлы конфигурации также входят в WEB-INF.

Что касается WEB-INF / classes - он существует в любом веб-приложении, потому что это папка, в которую помещаются все скомпилированные исходники (не JARS, а скомпилированные файлы .java, которые вы написали сами).

Артем Москалев
источник
4

Это соглашение соблюдается по соображениям безопасности. Например, если неавторизованному лицу разрешен доступ к корневому файлу JSP напрямую с URL-адреса, он может перемещаться по всему приложению без какой-либо аутентификации и иметь доступ ко всем защищенным данным.


источник
Не будет ли файл JSP искать сеанс запроса? И если он не найдет ничего, он не будет отображать некоторые части сайта.
парсер
3

Существует соглашение (не обязательно) о размещении страниц jsp в каталоге WEB-INF, чтобы их нельзя было глубоко связать или добавить в закладки. Таким образом, все запросы к странице JSP должны быть направлены через наше приложение, чтобы пользовательский опыт гарантирован.

Акшай Виджай Джайн
источник