web.xml vs inicializador com Spring

web.xml vs inicializador com Spring

*1. Visão geral *

Neste artigo, abordaremos três abordagens diferentes de configuração de um DispatcherServlet disponível nas versões recentes do _Spring Framework: _

  1. Começaremos com uma configuração XML e um arquivo web.xml

  2. Em seguida, migraremos a declaração do Servlet do arquivo web.xml para a configuração Java, mas deixaremos qualquer outra configuração em XML

  3. Finalmente, na terceira e última etapa da refatoração, teremos um projeto 100% configurado em Java

===* 2. O DispatcherServlet *

Um dos conceitos principais do Spring MVC é o DispatcherServlet. A documentação da mola define como:

_ Um expedidor central para manipuladores/controladores de solicitações HTTP, por exemplo para controladores da interface do usuário da Web ou exportadores de serviços remotos baseados em HTTP. Despacha para manipuladores registrados para processar uma solicitação da Web, fornecendo recursos convenientes de mapeamento e tratamento de exceções. _

Basicamente, o DispatcherServlet é o ponto de entrada de todos os aplicativos Spring MVC. Seu objetivo é interceptar solicitações HTTP e enviá-las para o componente certo que saberá como lidar com isso.

===* 3. Configuração com web.xml *

Se você lida com projetos Spring legados, é muito comum encontrar a configuração XML e até Spring 3.1, a única maneira de configurar o DispatcherServlet era com o arquivo WEB-INF/web.xml. Nesse caso, são necessárias duas etapas.

Vamos ver um exemplo de configuração - o primeiro passo é a declaração do Servlet:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Com este bloco de XML, estamos declarando um servlet que:

  1. É nomeado "dispatcher"

  2. É uma instância de org.springframework.web.servlet.DispatcherServlet

  3. Será inicializado com um parâmetro chamado contextConfigLocation que contém o caminho para a configuração XML

load-on-startup é um valor inteiro que especifica a ordem de carregamento de vários servlets. Portanto, se você precisar declarar mais de um servlet, poderá definir em qual ordem eles serão inicializados. Servlets marcados com números inteiros inferiores são carregados antes de servlets marcados com números inteiros mais altos.

Agora nosso servlet está configurado. A segunda etapa é declarar um servlet-mapping:

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Com o mapeamento do servlet, estamos limitando-o por seu nome a um URL pattern que especifica quais solicitações de HTTP serão tratadas por ele.

===* 4. Configuração híbrida *

Com a adoção da versão 3.0 das Servlet APIs, o arquivo web.xml tornou-se opcional e agora podemos usar o Java para configurar o DispatcherServlet.

Podemos registrar um servlet implementando um WebApplicationInitializer. Isso é equivalente à configuração XML acima:

public class MyWebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) {
        XmlWebApplicationContext context = new XmlWebApplicationContext();
        context.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");

        ServletRegistration.Dynamic dispatcher = container
          .addServlet("dispatcher", new DispatcherServlet(context));

        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

Neste exemplo, somos:

  1. Implementando a interface WebApplicationInitializer

  2. Substituindo o método onStartup, criamos um novo XmlWebApplicationContext configurado com o mesmo arquivo passado como contextConfigLocation para o servlet no exemplo XML

  3. Em seguida, estamos criando uma instância de DispatcherServlet com o novo contexto que acabamos de instanciar

  4. E, finalmente, estamos registrando o servlet com um mapeamento URL pattern

Portanto, usamos Java para declarar o servlet e vinculá-lo a um URL mapping, mas mantivemos a configuração em um arquivo XML separado: dispatcher-config.xml.

===* 5. 100% Java Configuração *

Com essa abordagem, nosso servlet é declarado em Java , , mas ainda precisamos de um arquivo XML para configurá-lo. Com WebApplicationInitializer, você pode obter uma configuração 100% Java.

Vamos ver como podemos refatorar o exemplo anterior.

A primeira coisa que precisamos fazer é criar o contexto do aplicativo para o servlet.

Desta vez, usaremos um contexto baseado em anotações para que possamos usar Java e anotações para configuração e remover a necessidade de arquivos XML como dispatcher-config.xml:

AnnotationConfigWebApplicationContext context
  = new AnnotationConfigWebApplicationContext();

Esse tipo de contexto pode ser configurado registrando uma classe de configuração:

context.register(AppConfig.class);

Ou definindo um pacote inteiro que será verificado para as classes de configuração:

context.setConfigLocation("com.example.app.config");

Agora que nosso contexto de aplicativo é criado, podemos adicionar um ouvinte ao ServletContext que carregará o contexto:

container.addListener(new ContextLoaderListener(context));

A próxima etapa é criar e registrar nosso servlet de expedidor:

ServletRegistration.Dynamic dispatcher = container
  .addServlet("dispatcher", new DispatcherServlet(context));

dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");

Agora nosso WebApplicationInitializer deve ficar assim:

public class MyWebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) {
        AnnotationConfigWebApplicationContext context
          = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("com.example.app.config");

        container.addListener(new ContextLoaderListener(context));

        ServletRegistration.Dynamic dispatcher = container
          .addServlet("dispatcher", new DispatcherServlet(context));

        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

A configuração de Java e anotação oferece muitas vantagens. Geralmente, isso leva a configurações mais curtas e concisas e as anotações fornecem mais contexto às declarações, pois são co-localizadas com o código que elas configuram.

Mas nem sempre é uma maneira preferível ou até possível. Por exemplo, alguns desenvolvedores podem preferir manter o código e a configuração separados ou talvez seja necessário trabalhar com código de terceiros que não pode ser modificado.

===* 6. Conclusão*

Neste artigo, abordamos diferentes maneiras de configurar um DispatcherServlet no Spring 3.2 + _ e cabe a você decidir qual usar com base em suas preferências. _Spring acomodará a sua decisão o que você escolher.

Você pode encontrar o código-fonte desse artigo no Github here e https://github.com/eugenp/tutorials/tree/master/spring-mvc-xml [aqui].