Um aplicativo da Web Java sem um web.xml

Um aplicativo da Web Java sem um web.xml

1. Visão geral

Neste tutorial, estamos criando um aplicativo da web Java usandoServlet 3.0+.

Vamos dar uma olhada em três anotações -@WebServlet,@WebFilter e@WebListener - que podem nos ajudar a nix nossos arquivosweb.xml.

2. A dependência do Maven

Para usar essas novas anotações, precisamos incluir a dependênciajavax.servlet-api:


    javax.servlet
    javax.servlet-api
    4.0.1

3. Configuração baseada em XML

Antes do Servlet 3.0, configurávamos um aplicativo da web Java em um arquivoweb.xml:


    
        com.example.servlets3.web.listeners.RequestListener
    
    
        uppercaseServlet
        com.example.servlets3.web.servlets.UppercaseServlet
    
    
        uppercaseServlet
        /uppercase
    
    
        emptyParamFilter
        com.example.servlets3.web.filters.EmptyParamFilter
    
    
        emptyParamFilter
        /uppercase
    

Vamos começar substituindo cada seção de configuração pelas respectivas anotações introduzidas no Servlet 3.0.

4. Servlets

JEE 6 fornecido com Servlet 3.0 que nos permite usar anotações para definições de servlet, minimizando o uso de um arquivoweb.xml para um aplicativo da web.

Por exemplo, podemos definir um servlet e expô-lo com a anotação@WebServlet

Vamos definir um servlet para o padrão de URL/uppercase. Isso transformará o valor do parâmetro de solicitaçãoinput em maiúsculas:

@WebServlet(urlPatterns = "/uppercase", name = "uppercaseServlet")
public class UppercaseServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
        String inputString = request.getParameter("input").toUpperCase();

        PrintWriter out = response.getWriter();
        out.println(inputString);
    }
}

Note that we defined a name for the servlet (uppercaseServlet) that we can now reference. Faremos uso disso na próxima seção.

Com a anotação@WebServlet, estamos substituindo as seçõesservlet eservlet-mapping do arquivoweb.xml.

5. Filtros

UmFilter é um objeto usado para interceptar solicitações ou respostas, executando tarefas de pré ou pós-processamento.

Podemos definir um filtro com a anotação@WebFilter.

Vamos criar um filtro para verificar se o parâmetro de solicitaçãoinput está presente:

@WebFilter(urlPatterns = "/uppercase")
public class EmptyParamFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
      FilterChain filterChain) throws IOException, ServletException {
        String inputString = servletRequest.getParameter("input");

        if (inputString != null && inputString.matches("[A-Za-z0-9]+")) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            servletResponse.getWriter().println("Missing input parameter");
        }
    }

    // implementations for other methods
}

Com a anotação@WebFilter, estamos substituindo as seçõesfilter efilter-mapping do arquivoweb.xml.

6. Ouvintes

Freqüentemente, precisaremos acionar ações com base em certos eventos. É aqui que os ouvintes vêm em socorro. Esses objetos escutam um evento e executam o comportamento que especificamos.

Como anteriormente, podemos definir um ouvinte com a anotação@WebListener.

Vamos criar um listener que conta cada vez que realizamos uma solicitação ao servidor. Vamos implementarServletRequestListener, ouvindoServletRequestEvents:

@WebListener
public class RequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent event) {
        HttpServletRequest request = (HttpServletRequest)event.getServletRequest();
        if (!request.getServletPath().equals("/counter")) {
            ServletContext context = event.getServletContext();
            context.setAttribute("counter", (int) context.getAttribute("counter") + 1);
        }
    }

    // implementations for other methods
}

Observe que estamos excluindo as solicitações para o padrão de URL/counter.

Com a anotação@WebListener, estamos substituindo a seçãolistener do arquivoweb.xml.

7. Construir e executar

Para aqueles que estão acompanhando, observe que, para teste, há um segundo servlet que adicionamos para o endpoint/counter que simplesmente retorna o atributo de contexto do servletcounter.

Então, vamos usarTomcat como o servidor de aplicativos.

Se estivermos usando uma versão demaven-war-plugin anterior a 3.1.0, precisaremos definir a propriedadefailOnMissingWebXml to false.

Agora, podemosdeploy our .war file to Tomcat e acessar nossos servlets.

Vamos experimentar nosso endpoint/uppercase:

curl http://localhost:8080/spring-mvc-java/uppercase?input=texttouppercase

TEXTTOUPPERCASE

E também devemos ver a aparência do nosso tratamento de erros:

curl http://localhost:8080/spring-mvc-java/uppercase

Missing input parameter

E, finalmente, um teste rápido do nosso ouvinte:

curl http://localhost:8080/spring-mvc-java/counter

Request counter: 2

8. XML ainda necessário

Mesmo, com todos os recursos introduzidos no Servlet 3.0, existem alguns casos de uso em que ainda precisaremos de um arquivoweb.xml, entre eles:

  • We can’t define the filter order with annotations - ainda precisamos da seção<filter-mapping> se tivermos vários filtros que precisamos aplicar em uma ordem específica

  • Para definir umsession timeout, ainda precisamos usar a seção<session-config>

  • Ainda precisamos do elemento<security-role> para autorização baseada em contêiner

  • E para especificar os arquivos de boas-vindas, ainda precisaremos de uma seção<welcome-file-list>

Ou o Servlet 3.0 também introduziu algunsprogrammatic support via ServletContainerInitializer, que também podem preencher algumas dessas lacunas.

9. Conclusão

Neste tutorial, configuramos um aplicativo web Java sem usar o arquivoweb.xml, exercitando as anotações equivalentes.

Como sempre, o código-fonte deste tutorial pode ser encontrado emGitHub. Além disso, um aplicativo que usa o arquivo web.xml tradicional também pode ser encontrado emGitHub.

Para uma abordagem baseada em Spring, vá para nosso tutorialweb.xml vs. Initializer with Spring.