Jeg jobber med en Java EE-webapplikasjon med følgende kildekodestruktur:
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
Den delen jeg er interessert i er WEB-INF
- den inneholder web.xml
, XML-filer for oppsett av servlets, Spring bean wiring contexts og JSP tags og views.
Jeg prøver å forstå hva som begrenser/definerer denne strukturen. Må for eksempel JSP-filer alltid ligge i WEB-INF
, eller kan de ligge et annet sted? Og er det noe annet som kan ligge i WEB-INF
? Wikipedia's WAR-filer nevner classes
for Java-klasser og lib
for JAR-filer - jeg er ikke sikker på om jeg helt har forstått når disse trengs i tillegg til de andre kildefilplasseringene.
Servlet 2.4-spesifikasjonen sier dette om WEB-INF (side 70):
Det finnes en spesiell katalog i applikasjonshierarkiet med navnet
WEB-INF
. Denne katalogen inneholder alt som er relatert til applikasjonen som ikke ligger i applikasjonens dokumentrot. Katalogen nodenWEB-INF
er ikke en del av det offentlige dokumenttreet til applikasjonen. applikasjonen. Ingen filer som finnes i katalogenWEB-INF
, kan vises direkte til en klient direkte til en klient av beholderen. Innholdet i katalogenWEB-INF
-katalogen er imidlertid synlig for servlet-koden ved hjelp avgetResource
oggetResource
. oggetResourceAsStream
metodeanrop påServletContext
, og kan også være eksponert ved hjelp avRequestDispatcher
-kallene.
Dette betyr at WEB-INF
-ressurser er tilgjengelige for ressurslasteren i webapplikasjonen og ikke direkte synlige for allmennheten.
Dette er grunnen til at mange prosjekter plasserer ressurser som JSP-filer, JARs/biblioteker og egne klassefiler, egenskapsfiler eller annen sensitiv informasjon i WEB-INF
-mappen. Ellers ville de vært tilgjengelige ved hjelp av en enkel statisk URL (nyttig for å laste CSS eller Javascript for eksempel).
Fra et teknisk perspektiv kan JSP-filene ligge hvor som helst. I Spring kan du for eksempel eksplisitt konfigurere dem til å ligge i WEB-INF
:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" >
</bean>
Mappene WEB-INF/classes
og WEB-INF/lib
som er nevnt i Wikipedias artikkel WAR-filer, er eksempler på mapper som Servlet-spesifikasjonen krever ved kjøring.
**Det er viktig å skille mellom strukturen i et prosjekt og strukturen i den resulterende WAR-filen.
Strukturen i prosjektet vil i noen tilfeller delvis gjenspeile strukturen i WAR-filen (for statiske ressurser som JSP-filer eller HTML- og JavaScript-filer), men dette er ikke alltid tilfelle.
***Overgangen fra prosjektstrukturen til den resulterende WAR-filen gjøres av en byggeprosess.
Selv om du vanligvis står fritt til å designe din egen byggeprosess, bruker de fleste i dag en standardisert tilnærming som Apache Maven. Maven definerer blant annet standardverdier for hvilke ressurser i prosjektstrukturen som skal tilordnes hvilke ressurser i den resulterende artefakten (den resulterende artefakten er WAR-filen i dette tilfellet). I noen tilfeller består mappingen av en ren kopieringsprosess, i andre tilfeller inkluderer mappingen en transformasjon, for eksempel filtrering eller kompilering.
*Ett eksempel: Mappen WEB-INF/classes
vil senere inneholde alle kompilerte javaklasser og ressurser (src/main/java
og src/main/resources
) som må lastes inn av Classloader for å starte applikasjonen.
*Et annet eksempel: Mappen WEB-INF/lib
vil senere inneholde alle jar-filer som applikasjonen trenger. I et maven-prosjekt håndteres avhengighetene for deg, og maven kopierer automatisk de nødvendige jar-filene til mappen WEB-INF/lib
for deg. Det forklarer hvorfor du ikke har en lib
-mappe i et maven-prosjekt.
Når du distribuerer en Java EE-webapplikasjon (med eller uten rammeverk), må strukturen følge noen krav/spesifikasjoner. Disse spesifikasjonene kommer fra:
- Servlet-containeren (f.eks. Tomcat)
- Java Servlet API
- Applikasjonsdomenet ditt
Krav til Servlet-containeren
Hvis du bruker Apache Tomcat, må rotkatalogen til applikasjonen plasseres i webapp-mappen. Det kan være annerledes hvis du bruker en annen servletcontainer eller applikasjonsserver;
Krav til Java Servlet API
Java Servlet API sier at rotkatalogen for applikasjonen må ha følgende struktur:
Applikasjonsnavn
|
|--META-INF
|--WEB-INF
|_web.xml <-- Her er konfigurasjonsfilen til webappen din (hvor du definerer servlets, filtre, lyttere...)
|_classes <--Her kommer alle klassene i webappen din, i henhold til pakkestrukturen du har definert. Kun
|_lib <--Her ligger alle bibliotekene (jars) som applikasjonen din trenger.
Disse kravene er definert av Java Servlet API;
3. Domenet til applikasjonen din;
Nå som du har fulgt kravene til Servlet-containeren (eller applikasjonsserveren) og kravene til Java Servlet API, kan du organisere de andre delene av webapplikasjonen basert på hva du trenger.
- Du kan plassere ressursene dine (JSP-filer, rene tekstfiler, skriptfiler) i rotkatalogen for applikasjonen. Men da kan folk få tilgang til dem direkte fra nettleseren, i stedet for at forespørslene behandles av logikken i applikasjonen din. For å forhindre at ressursene dine blir direkte tilgjengelige på denne måten, kan du legge dem i WEB-INF-katalogen, hvis innhold bare er tilgjengelig for serveren.
-Hvis du bruker noen rammeverk, bruker de ofte konfigurasjonsfiler. De fleste av disse rammeverkene (struts, spring, hibernate) krever at du legger konfigurasjonsfilene i classpath (katalogen "classes").
Du bør legge inn sider, eller deler av sider, som du ikke ønsker skal være offentlige, i WEB-INF. Vanligvis ligger JSP eller facelets utenfor WEB-INF, men i dette tilfellet er de lett tilgjengelige for alle brukere. Hvis du har noen autorisasjonsbegrensninger, kan WEB-INF brukes til dette.
WEB-INF/lib kan inneholde tredjepartsbiblioteker som du ikke ønsker å pakke på systemnivå (JAR-er kan være tilgjengelige for alle applikasjonene som kjører på serveren), men bare for denne applikasjonen.
Generelt sett ligger mange konfigurasjonsfiler også i WEB-INF.
Når det gjelder WEB-INF/classes - den finnes i alle web-applikasjoner, fordi det er mappen der alle de kompilerte kildene er plassert (ikke JARS, men kompilerte .java-filer som du har skrevet selv).