Do czego służy WEB-INF w aplikacji internetowej Java EE?

177

Pracuję nad aplikacją internetową Java EE o następującej strukturze kodu źródłowego:

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

Interesuje mnie kawałek WEB-INF- zawiera web.xmlpliki XML do konfigurowania serwletów, konteksty okablowania Spring bean oraz znaczniki i widoki JSP.

Próbuję zrozumieć, co ogranicza / definiuje tę strukturę. Np. Czy pliki JSP zawsze musiałyby znajdować się w środku, WEB-INFczy mogą znajdować się gdzie indziej? I czy jest coś jeszcze, co może wejść WEB-INF? Wpis Wikipedii dotyczący plików WAR wspomina classeso klasach Java i libplikach JAR - nie jestem pewien, czy w pełni zrozumiałem, kiedy będą one potrzebne oprócz innych lokalizacji plików źródłowych.

Steve Chambers
źródło
1
To może być pomocne: gordondickens.com/wordpress/2012/07/03/…
smwikipedia
1
FYI… Aby dowiedzieć się, w jaki sposób kontenery serwletów ładują się z WEB-INFi innych miejsc, zobacz pytanie Kontrolowanie ścieżki klas w serwlecie , zwłaszcza tę odpowiedź .
Basil Bourque

Odpowiedzi:

216

Specyfikacja Servlet 2.4 mówi tak o WEB-INF (strona 70):

W nazwanej hierarchii aplikacji istnieje katalog specjalny WEB-INF. Ten katalog zawiera wszystkie rzeczy związane z aplikacją, których nie ma w katalogu głównym dokumentu aplikacji. Węzeł nie jest częścią drzewa dokumentu publicznego wniosku . Żaden plik znajdujący się w katalogu nie może być udostępniony bezpośrednio klientowi przez kontener. Jednak zawartość katalogu jest widoczna dla kodu serwletu przy użyciu wywołań metody i w i może być ujawniona przy użyciu wywołań.WEB-INFWEB-INFWEB-INFgetResourcegetResourceAsStreamServletContextRequestDispatcher

Oznacza to, że WEB-INFzasoby są dostępne dla modułu ładującego zasoby Twojej aplikacji internetowej i nie są bezpośrednio widoczne dla publiczności.

Dlatego wiele projektów umieszcza swoje zasoby, takie jak pliki JSP, JAR / biblioteki i własne pliki klas, pliki właściwości lub inne poufne informacje w WEB-INFfolderze. W przeciwnym razie byłyby dostępne za pomocą prostego statycznego adresu URL (przydatnego na przykład do załadowania CSS lub JavaScript).

Z technicznego punktu widzenia pliki JSP mogą być jednak wszędzie. Na przykład wiosną możesz skonfigurować je tak, aby były WEB-INFjawnie w:

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

Te WEB-INF/classesi WEB-INF/libfoldery wymienione w Wikipedii WAR pliki artykule przedstawiono przykłady folderów wymaganych w specyfikacji Servlet przy starcie.

Ważne jest, aby odróżnić strukturę projektu od struktury wynikowego pliku WAR.

Struktura projektu w niektórych przypadkach będzie częściowo odzwierciedlać strukturę pliku WAR (w przypadku zasobów statycznych, takich jak pliki JSP lub pliki HTML i JavaScript, ale nie zawsze tak jest.

Przejście ze struktury projektu do wynikowego pliku WAR odbywa się w procesie kompilacji.

Chociaż zwykle możesz zaprojektować własny proces kompilacji, obecnie większość ludzi będzie korzystać ze standardowego podejścia, takiego jak Apache Maven . Między innymi Maven definiuje wartości domyślne, dla których zasoby w strukturze projektu są odwzorowywane na jakie zasoby w wynikowym artefakcie (w tym przypadku wynikowym artefaktem jest plik WAR). W niektórych przypadkach mapowanie składa się ze zwykłego procesu kopiowania, w innych przypadkach proces mapowania obejmuje transformację, taką jak filtrowanie lub kompilowanie i inne.

Jeden przykład : WEB-INF/classesfolder będzie później zawierał wszystkie skompilowane klasy i zasoby Java ( src/main/javai src/main/resources), które muszą zostać załadowane przez Classloader, aby uruchomić aplikację.

Inny przykład : WEB-INF/libfolder będzie później zawierał wszystkie pliki jar potrzebne aplikacji. W projekcie maven zależności są zarządzane za Ciebie, a maven automatycznie kopiuje potrzebne pliki jar do WEB-INF/libfolderu za Ciebie. To wyjaśnia, dlaczego nie masz libfolderu w projekcie maven.

mwhs
źródło
2
Zmiana w Servlet 3.0 i 3.1 ( JSR 340 ) umożliwia obsługę statycznych zasobów i stron JSP z JAR-a przechowywanego w WEB-INF / lib. Cytując specyfikację Servlet 3.1 w sekcji 10.5: Z wyjątkiem statycznych zasobów i stron JSP spakowanych w META-INF / resources pliku JAR, który znajduje się w katalogu WEB-INF / lib, żadne inne pliki zawarte w katalogu WEB-INF nie mogą być obsługiwany bezpośrednio przez kontener do klienta. Więc wyjątek dotyczy jedynie: WAR> WEB-INF> lib> JARplik>resources
Basil Bourque
1
Ups, z moim komentarzem powyżej, zmiany, ostatnie zdanie do: statyczne pliki mogą być podawane od: WARplik> WEB-INF> lib> JARplik> META-INF> resources> yourStaticFilesGoHere .
Basil Bourque,
@mwhs Proponuję zrewidować swoją odpowiedź, dodając nową sekcję Servlet 3 i oznaczyć aktualną zawartość jako sekcję Servlet 2.
Basil Bourque,
61

Podczas wdrażania aplikacji internetowej Java EE (przy użyciu frameworków lub bez) jej struktura musi być zgodna z pewnymi wymaganiami / specyfikacjami. Specyfikacje te pochodzą z:

  • Kontener serwletów (np. Tomcat)
  • Java Servlet API
  • Twoja domena aplikacji
  1. Wymagania dotyczące kontenera serwletów
    Jeśli używasz Apache Tomcat, katalog główny aplikacji musi znajdować się w folderze webapp. Może się to różnić, jeśli używasz innego kontenera serwletów lub serwera aplikacji.

  2. Wymagania
    Java Servlet API Java Servlet API stwierdza, że ​​katalog główny aplikacji musi mieć następującą strukturę:

    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

Te wymagania są definiowane przez Java Servlet API.

3. Twoja domena aplikacji
Po spełnieniu wymagań kontenera serwletów (lub serwera aplikacji) i wymagań Java Servlet API, możesz zorganizować inne części swojej aplikacji internetowej w oparciu o to, czego potrzebujesz.
- Możesz umieścić swoje zasoby (pliki JSP, zwykłe pliki tekstowe, pliki skryptów) w katalogu głównym aplikacji. Ale wtedy ludzie mogą uzyskać do nich dostęp bezpośrednio z przeglądarki, zamiast przetwarzania ich żądań przez jakąś logikę zapewnianą przez twoją aplikację. Tak więc, aby zapobiec bezpośredniemu dostępowi do zasobów w ten sposób, możesz umieścić je w katalogu WEB-INF, którego zawartość jest dostępna tylko dla serwera.
-Jeśli używasz niektórych frameworków, często używają one plików konfiguracyjnych. Większość tych frameworków (struts, spring, hibernate) wymaga umieszczenia ich plików konfiguracyjnych w ścieżce klas (katalogu „classes”).

Patrick B.
źródło
12

Powinieneś umieścić w WEB-INF wszystkie strony lub fragmenty stron, których nie chcesz, aby były publiczne. Zwykle JSP lub facelety znajdują się poza WEB-INF, ale w tym przypadku są łatwo dostępne dla każdego użytkownika. Jeśli masz jakieś ograniczenia autoryzacji, możesz do tego użyć WEB-INF.

WEB-INF / lib może zawierać biblioteki innych firm, których nie chcesz pakować na poziomie systemu (pliki JAR mogą być dostępne dla wszystkich aplikacji uruchomionych na serwerze), ale tylko dla tej konkretnej aplikacji.

Ogólnie rzecz biorąc, wiele plików konfiguracyjnych również trafia do WEB-INF.

Jeśli chodzi o WEB-INF / classes - istnieje w każdej aplikacji internetowej, ponieważ jest to folder, w którym znajdują się wszystkie skompilowane źródła (nie JARS, ale skompilowane pliki .java, które sam napisałeś).

Artem Moskalev
źródło
4

Ta konwencja jest przestrzegana ze względów bezpieczeństwa. Na przykład, jeśli nieupoważniona osoba ma dostęp do głównego pliku JSP bezpośrednio z adresu URL, może ona poruszać się po całej aplikacji bez żadnego uwierzytelniania i może uzyskać dostęp do wszystkich zabezpieczonych danych.


źródło
Czy plik jsp nadal nie szuka sesji żądania? A jeśli nie znajdzie żadnego, nie wyświetli niektórych części witryny.
parsecer
3

Istnieje konwencja (niekonieczna) umieszczania stron jsp w katalogu WEB-INF, aby nie można było do nich prowadzić głębokich linków ani zakładek. W ten sposób wszystkie żądania do strony jsp muszą być kierowane przez naszą aplikację, aby zagwarantować komfort użytkowania.

Akshay Vijay Jain
źródło