Como configurar o descritor de implantação web.xml

O arquivo web.xml é usado apenas na implantação de um aplicativo Java em um ambiente de execução que inclui o servidor Eclipse Jetty 9/Servlet 3. Para ver mais detalhes, consulte o ambiente de execução Eclipse Jetty 9.3.

Os aplicativos da Web em Java usam um arquivo descritor de implantação para determinar como os URLs são mapeados para servlets, quais URLs exigem autenticação e outras informações. Esse arquivo é chamado web.xml e fica armazenado no WAR do aplicativo no diretório WEB-INF/. web.xml faz parte da norma de servlet para aplicativos web.

Para mais informações sobre o padrão web.xml, consulte a especificação do Servlet.

Sobre os descritores de implantação

O descritor de implantação de um aplicativo da Web indica as classes, os recursos e a configuração do aplicativo e como o servidor da Web os utiliza para veicular solicitações da Web. Ao receber uma solicitação do aplicativo, o servidor da Web usa o descritor de implantação a fim de mapear o URL da solicitação para o código que precisa processá-la.

O descritor de implantação é um arquivo chamado web.xml. Ele fica armazenado no WAR do aplicativo no diretório WEB-INF/. O arquivo é um arquivo XML cujo elemento raiz é <web-app>.

Veja a seguir um exemplo web.xml simples de que mapeia todos os caminhos de URL (/*) para a classe de servlet = mysite.server.ComingSoonServlet:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>comingsoon</servlet-name>
        <servlet-class>mysite.server.ComingSoonServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>comingsoon</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

Servlets e caminhos do URL

web.xml define os mapeamentos entre os caminhos de URL e os servlets que processarão as solicitações com esses caminhos. O servidor web usa essa configuração para identificar o servlet que processará determinada solicitação e chamar o método de classe que corresponda ao método de solicitação (por exemplo, o método doGet() para solicitações HTTP GET).

Para mapear um URL para um servlet, você precisa declarar o servlet com o elemento <servlet> e, em seguida, definir um mapeamento de um caminho de URL para uma declaração de servlet com o elemento <servlet-mapping>.

O elemento <servlet> declara o servlet, incluindo um nome usado para fazer o encaminhamento para o servlet por outros elementos no arquivo, a classe a ser usada para o servlet e os parâmetros de inicialização. Você pode declarar vários servlets usando a mesma classe com parâmetros diferentes de inicialização. O nome de cada servlet precisa ser exclusivo no descritor de implantação.

    <servlet>
        <servlet-name>redteam</servlet-name>
        <servlet-class>mysite.server.TeamServlet</servlet-class>
        <init-param>
            <param-name>teamColor</param-name>
            <param-value>red</param-value>
        </init-param>
        <init-param>
            <param-name>bgColor</param-name>
            <param-value>#CC0000</param-value>
        </init-param>
    </servlet>

    <servlet>
        <servlet-name>blueteam</servlet-name>
        <servlet-class>mysite.server.TeamServlet</servlet-class>
        <init-param>
            <param-name>teamColor</param-name>
            <param-value>blue</param-value>
        </init-param>
        <init-param>
            <param-name>bgColor</param-name>
            <param-value>#0000CC</param-value>
        </init-param>
    </servlet>

O elemento <servlet-mapping> especifica um padrão de URL e o nome de um servlet declarado a ser usado para solicitações cujo URL corresponde ao padrão. O padrão de URL pode usar um asterisco (*) no início ou no fim para indicar zero ou um número maior de determinado caractere. O padrão não é compatível com caracteres curinga no meio de uma string e não permite vários desses caracteres em um padrão. O padrão corresponde ao caminho completo do URL, começando com (e incluindo) a barra (/) seguida do nome de domínio.

    <servlet-mapping>
        <servlet-name>redteam</servlet-name>
        <url-pattern>/red/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>blueteam</servlet-name>
        <url-pattern>/blue/*</url-pattern>
    </servlet-mapping>

Nesse exemplo, uma solicitação do URL http://www.example.com/blue/teamProfile é processada pela classe TeamServlet, com o parâmetro teamColor igual a blue e o parâmetro bgColor igual a #0000CC. O servlet pode obter a parte do caminho de URL correspondida pelo caractere curinga usando o método getPathInfo() do objeto ServletRequest.

O servlet pode acessar seus parâmetros de inicialização obtendo sua configuração de servlet usando seu próprio método getServletConfig() e, em seguida, chamando o método getInitParameter() no objeto de configuração usando o nome do parâmetro como um argumento.

        String teamColor = getServletConfig().getInitParameter("teamColor");

JSPs

Um app pode usar páginas do JavaServer (JSPs, na sigla em inglês) para implementar páginas da Web. JSPs são servlets definidos por meio do uso de conteúdo estático, como HTML, combinado ao código Java.

O App Engine é compatível com a compilação automática e o mapeamento de URLs para JSPs. Um arquivo JSP no WAR do aplicativo (fora de WEB-INF/) com um nome que termina em .jsp é compilado automaticamente em uma classe de servlet e mapeado para o caminho de URL equivalente ao caminho do arquivo JSP na raiz do WAR. Por exemplo, se um aplicativo tiver um arquivo JSP chamado start.jsp em um subdiretório chamado register/ do próprio WAR, o App Engine o compilará e o mapeará para o caminho de URL /register/start.jsp.

Se você desejar ter mais controle sobre o mapeamento de JSP para um URL, pode especificar o mapeamento explicitamente declarando-o com um elemento <servlet> no descritor de implantação. Em vez de um elemento <servlet-class>, especifique um elemento <jsp-file> com o caminho do arquivo JSP na raiz do WAR. O elemento <servlet> da JSP pode conter parâmetros de inicialização.

    <servlet>
        <servlet-name>register</servlet-name>
        <jsp-file>/register/start.jsp</jsp-file>
    </servlet>

    <servlet-mapping>
        <servlet-name>register</servlet-name>
        <url-pattern>/register/*</url-pattern>
    </servlet-mapping>

É possível instalar as bibliotecas de tags da JSP com o elemento <taglib>. Uma biblioteca de tags tem um caminho para o arquivo TLD do JSP (<taglib-location>) e um URI usado pelas JSPs para selecionar a biblioteca para carregamento (<taglib-uri>). Observe que o App Engine fornece a biblioteca de tags padrão de páginas JavaServer (JSTL) e você não precisa instalá-la.

    <taglib>
        <taglib-uri>/escape</taglib-uri>
        <taglib-location>/WEB-INF/escape-tags.tld</taglib-location>
    </taglib>

Lista de arquivos de boas-vindas

Quando os URLs do site representam caminhos para arquivos estáticos ou JSPs no WAR, costuma ser bom também ter caminhos para diretórios fazendo algo útil. Um usuário que visita o caminho do URL /help/accounts/password.jsp para conseguir informações sobre senhas de contas pode tentar visitar /help/accounts/ para encontrar uma página que introduza a documentação do sistema de contas. O descritor de implantação pode especificar uma lista de nomes de arquivo que o servidor precisa tentar quando o usuário acessa um caminho que representa um subdiretório do WAR ainda não mapeado explicitamente para um servlet. O padrão do servlet chama isso de "lista de arquivos de boas-vindas".

Por exemplo, se usuário acessar o caminho de URL /help/accounts/, o seguinte elemento <welcome-file-list> no descritor de implantação solicitará que o servidor procure help/accounts/index.jsp e help/accounts/index.html antes de comunicar que o URL não existe:

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

Filtros

Um filtro é uma classe que atua sobre solicitações, como um servlet, mas que pode permitir que o processamento da solicitação continue com outros filtros ou servlets. Um filtro pode realizar uma tarefa auxiliar, como geração de registros, realização de verificações especializadas de autenticação ou anotação dos objetos de solicitação ou de resposta, antes de chamar o servlet. Os filtros permitem escrever tarefas de processamento de solicitação no descritor de implantação.

Uma classe de filtro implementa a interface javax.servlet.Filter, incluindo o método doFilter(). Veja a seguir uma implementação de filtro simples que registra uma mensagem e passa o controle pela cadeia, que pode incluir outros filtros ou um servlet, conforme indicado pelo descritor de implantação:

package mysite.server;

import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class LogFilterImpl implements Filter {

    private FilterConfig filterConfig;
    private static final Logger log = Logger.getLogger(LogFilterImpl.class.getName());

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
        throws IOException, ServletException {
        log.warning("Log filter processed a " + getFilterConfig().getInitParameter("logType")
            + " request");

        filterChain.doFilter(request, response);
    }

    public FilterConfig getFilterConfig() {
        return filterConfig;
    }

    public void init(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    public void destroy() {}

}

Assim como os servlets, você pode configurar um filtro no descritor de implantação declarando-o com o elemento <filter> e, em seguida, mapeando-o para um padrão de URL com o elemento <filter-mapping>. Também é possível mapear filtros diretamente para outros servlets.

O elemento <filter> contém um <filter-name>, <filter-class> e elementos <init-param> opcionais.

    <filter>
        <filter-name>logSpecial</filter-name>
        <filter-class>mysite.server.LogFilterImpl</filter-class>
        <init-param>
            <param-name>logType</param-name>
            <param-value>special</param-value>
        </init-param>
    </filter>

O elemento <filter-mapping> contém um <filter-name>, que corresponde ao nome de um filtro declarado e um elemento <url-pattern>, para aplicar o filtro aos URLs, ou um elemento <servlet-name>, que corresponde ao nome de um servlet declarado para aplicar o filtro sempre que o servlet for chamado.

    <!-- Log for all URLs ending in ".special" -->
    <filter-mapping>
        <filter-name>logSpecial</filter-name>
        <url-pattern>*.special</url-pattern>
    </filter-mapping>

    <!-- Log for all URLs that use the "comingsoon" servlet -->
    <filter-mapping>
        <filter-name>logSpecial</filter-name>
        <servlet-name>comingsoon</servlet-name>
    </filter-mapping>

Gerenciadores de erros

Com o descritor de implantação, você pode personalizar o que o servidor envia ao usuário quando ocorre um erro. O servidor poderá exibir um local alternativo de página quando estiver prestes a enviar um determinado código de status HTTP ou quando um servlet gerar uma determinada exceção Java.

O elemento <error-page> contém um elemento <error-code> com um valor de código de erro HTTP (como 500) ou um <exception-type> com o nome da classe da exceção esperada (como java.io.IOException). Ele também contém um <location> que contém o caminho do URL do recurso a ser exibido quando o erro ocorre.

    <error-page>
        <error-code>500</error-code>
        <location>/errors/servererror.jsp</location>
    </error-page>

Recursos do web.xml sem suporte

Os seguintes recursos web.xml não são compatíveis com o App Engine:

  • O App Engine oferece suporte ao elemento <load-on-startup> para declarações de servlet. No entanto, o carregamento ocorre efetivamente durante a primeira solicitação processada pela instância do servidor da Web, e não antes dela.
  • Alguns elementos do descritor de implantação aceitam um nome de exibição legível, uma descrição e um ícone a serem usados em ambientes de desenvolvimento integrado. O App Engine não os utiliza e os ignora.
  • O App Engine não oferece suporte a variáveis de ambiente JNDI (<env-entry>).
  • O App Engine não oferece suporte a recursos EJB (<resource-ref>).
  • Não são aceitos filtros, notificações de destruição de servlets e contexto do servlets.
  • O elemento <distributable> é ignorado.
  • Não há suporte à programação do servlet com <run-at>.
  • As restrições de segurança não são compatíveis: para funcionalidade equivalente, consulte Autenticar para os serviços do Cloud usando bibliotecas de cliente.
  • Não há suporte para CONFIDENCIAL em web.xml.