Para que é utilizado o WEB-INF em um aplicativo da web Java EE?

177

Estou trabalhando em um aplicativo Web Java EE com a seguinte estrutura de código-fonte:

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

O que mais me interessa é WEB-INF- ele contém web.xmlarquivos XML para configurar servlets, contextos de fiação do bean Spring e tags e visualizações JSP.

Estou tentando entender o que restringe / define essa estrutura. Por exemplo, os arquivos JSP sempre precisam estar dentro WEB-INFou podem estar em outro lugar? E há mais alguma coisa que possa entrar WEB-INF? A entrada de arquivos WAR da Wikipedia menciona classesclasses Java e libarquivos JAR - não sei se compreendi completamente quando isso seria necessário, além de outros locais de arquivos de origem.

Steve Chambers
fonte
1
Isso pode ser útil: gordondickens.com/wordpress/2012/07/03/…
smwikipedia
1
Para sua informação… Para aprender sobre como os contêineres de servlets são carregados WEB-INFe de outros locais, consulte a pergunta Controlando o caminho de classe em um servlet , especialmente esta resposta .
Basil Bourque

Respostas:

216

A especificação do Servlet 2.4 diz isso sobre o WEB-INF (página 70):

Um diretório especial existe dentro da hierarquia de aplicativos nomeada WEB-INF. Este diretório contém todos os itens relacionados ao aplicativo que não estão na raiz do documento. O WEB-INFnó não faz parte da árvore de documentos públicos do aplicativo . Nenhum arquivo contido no WEB-INFdiretório pode ser servido diretamente a um cliente pelo contêiner. No entanto, o conteúdo do WEB-INFdiretório é visível para o código do servlet usando as chamadas de método getResource e getResourceAsStreamno ServletContexte pode ser exposto usando as RequestDispatcherchamadas.

Isso significa que os WEB-INFrecursos são acessíveis ao carregador de recursos do seu aplicativo da Web e não diretamente visíveis ao público.

É por isso que muitos projetos colocam seus recursos como arquivos JSP, JARs / bibliotecas e seus próprios arquivos de classe ou arquivos de propriedades ou qualquer outra informação confidencial na WEB-INFpasta. Caso contrário, eles seriam acessíveis usando uma URL estática simples (útil para carregar CSS ou Javascript, por exemplo).

Seus arquivos JSP podem estar em qualquer lugar, do ponto de vista técnico. Por exemplo, no Spring, você pode configurá-los para serem WEB-INFexplicitamente:

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

As pastas WEB-INF/classese WEB-INF/libmencionadas no artigo de arquivos WAR da Wikipedia são exemplos de pastas exigidas pela especificação do Servlet em tempo de execução.

É importante fazer a diferença entre a estrutura de um projeto e a estrutura do arquivo WAR resultante.

A estrutura do projeto, em alguns casos, reflete parcialmente a estrutura do arquivo WAR (para recursos estáticos, como arquivos JSP ou arquivos HTML e JavaScript, mas esse nem sempre é o caso.

A transição da estrutura do projeto para o arquivo WAR resultante é feita por um processo de construção.

Enquanto você geralmente é livre para criar seu próprio processo de criação, hoje em dia a maioria das pessoas usa uma abordagem padronizada como o Apache Maven . Entre outras coisas, o Maven define padrões para quais recursos na estrutura do projeto são mapeados para quais recursos no artefato resultante (o artefato resultante é o arquivo WAR nesse caso). Em alguns casos, o mapeamento consiste em um processo de cópia simples; em outros casos, o processo de mapeamento inclui uma transformação, como filtragem ou compilação e outras.

Um exemplo : A WEB-INF/classespasta conterá posteriormente todas as classes e recursos Java compilados ( src/main/javae src/main/resources) que precisam ser carregados pelo Classloader para iniciar o aplicativo.

Outro exemplo : A WEB-INF/libpasta conterá posteriormente todos os arquivos jar necessários pelo aplicativo. Em um projeto maven, as dependências são gerenciadas por você e o maven copia automaticamente os arquivos jar necessários para a WEB-INF/libpasta. Isso explica por que você não tem uma libpasta em um projeto de preparação.

mwhs
fonte
2
A alteração no Servlet 3.0 e 3.1 ( JSR 340 ) permite servir recursos estáticos e JSPs de dentro de um JAR armazenado em WEB-INF / lib. Para citar a seção 10.5 da especificação do Servlet 3.1: Exceto pelos recursos estáticos e JSPs empacotados nos META-INF / resources de um arquivo JAR que reside no diretório WEB-INF / lib, nenhum outro arquivo contido no diretório WEB-INF servido diretamente a um cliente pelo contêiner. Portanto, a exceção se aplica somente a: WAR> WEB-INF> lib> JARfile>resources
Basil Bourque
1
Whoops, do meu comentário acima, alterar a última frase para: arquivos estáticos pode ser servido a partir de: WARfile> WEB-INF> lib> JARArquivo> META-INF> resources> yourStaticFilesGoHere .
Basil Bourque
@mwhs Sugiro que você reveja sua resposta com uma nova seção do Servlet 3 e rotule seu conteúdo atual como uma seção do Servlet 2.
Basil Bourque
61

Quando você implementa um aplicativo da web Java EE (usando estruturas ou não), sua estrutura deve seguir alguns requisitos / especificações. Essas especificações vêm de:

  • O contêiner do servlet (por exemplo, Tomcat)
  • API Java Servlet
  • O domínio do seu aplicativo
  1. Os requisitos de contêiner do servlet
    Se você usa o Apache Tomcat, o diretório raiz do seu aplicativo deve ser colocado na pasta webapp. Isso pode ser diferente se você usar outro contêiner de servlet ou servidor de aplicativos.

  2. Requisitos da API do Java Servlet A API do
    Java Servlet indica que o diretório do aplicativo raiz deve ter a seguinte estrutura:

    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

Esses requisitos são definidos pela Java Servlet API.

3. Seu domínio de aplicativo
Agora que você seguiu os requisitos do contêiner Servlet (ou servidor de aplicativos) e dos requisitos da API Java Servlet, é possível organizar as outras partes do seu aplicativo da Web com base no que você precisa.
- Você pode colocar seus recursos (arquivos JSP, arquivos de texto sem formatação, arquivos de script) no diretório raiz do aplicativo. Porém, as pessoas podem acessá-las diretamente do navegador, em vez de as solicitações serem processadas por alguma lógica fornecida pelo aplicativo. Portanto, para impedir que seus recursos sejam acessados ​​diretamente dessa maneira, você pode colocá-los no diretório WEB-INF, cujo conteúdo é acessível apenas pelo servidor.
-Se você usa algumas estruturas, elas costumam usar arquivos de configuração. A maioria dessas estruturas (struts, spring, hibernate) exige que você coloque seus arquivos de configuração no caminho de classe (o diretório "classes").

Patrick B.
fonte
12

Você deve colocar no WEB-INF as páginas ou partes de páginas que não deseja que sejam públicas. Geralmente, JSP ou facelets são encontrados fora do WEB-INF, mas, neste caso, são facilmente acessíveis para qualquer usuário. Caso você tenha algumas restrições de autorização, o WEB-INF pode ser usado para isso.

O WEB-INF / lib pode conter bibliotecas de terceiros que você não deseja compactar no nível do sistema (os JARs podem estar disponíveis para todos os aplicativos em execução no servidor), mas apenas para esta aplicação específica.

De um modo geral, muitos arquivos de configuração também entram no WEB-INF.

Quanto ao WEB-INF / classes - ele existe em qualquer aplicativo da web, porque é a pasta onde todas as fontes compiladas são colocadas (não JARS, mas arquivos .java compilados que você mesmo escreveu).

Artem Moskalev
fonte
4

Esta convenção é seguida por razões de segurança. Por exemplo, se uma pessoa não autorizada tiver permissão para acessar o arquivo JSP raiz diretamente da URL, poderá navegar por todo o aplicativo sem autenticação e acessar todos os dados protegidos.


fonte
O arquivo jsp ainda não procuraria a sessão de uma solicitação? E, se não encontrar nenhum, não exibirá algumas partes do site.
parsecer 14/02/19
3

Existe uma convenção (não necessária) de colocar as páginas jsp no diretório WEB-INF, para que não possam ser vinculadas ou marcadas com profundidade. Dessa forma, todos os pedidos para a página jsp devem ser direcionados através de nosso aplicativo, para garantir a experiência do usuário.

Akshay Vijay Jain
fonte