HandlerAdapters no Spring MVC

HandlerAdapters no Spring MVC

1. Visão geral

Neste artigo, vamos nos concentrar nas várias implementações de adaptadores de manipulador disponíveis na estrutura Spring.

2. O que é um Handleradapter?

OHandlerAdapter é basicamente uma interface que facilita o manuseio de solicitações HTTP de uma maneira muito flexível no Spring MVC.

É usado em conjunto comHandlerMapping, que mapeia um método para um URL específico.

ODispatcherServlet então usa umHandlerAdapter para invocar este método. O servlet não invoca o método diretamente - ele basicamente serve como uma ponte entre ele mesmo e os objetos do manipulador, levando a um design de acoplamento fraco.

Vamos dar uma olhada em vários métodos disponíveis nesta interface:

public interface HandlerAdapter {
    boolean supports(Object handler);

    ModelAndView handle(
      HttpServletRequest request,
      HttpServletResponse response,
      Object handler) throws Exception;

    long getLastModified(HttpServletRequest request, Object handler);
}

A APIsupports é usada para verificar se uma determinada instância do manipulador é compatível ou não. Este método deve ser chamado primeiro antes de chamar o métodohandle() desta interface, a fim de verificar se a instância do manipulador é compatível ou não.

A APIhandle é usada para lidar com uma solicitação HTTP específica. Este método é responsável por invocar o manipulador passando os objetosHttpServletRequesteHttpServletResponse como o parâmetro. O manipulador então executa a lógica do aplicativo e retorna um objetoModelAndView, que é então processado porDispatcherServlet.

3. Dependência do Maven

Vamos começar com a dependência Maven que precisa ser adicionada apom.xml:


    org.springframework
    spring-webmvc
    4.3.4.RELEASE

A versão mais recente do artefatospring-webmvc pode ser encontradahere.

4. Tipos deHandlerAdapter

4.1. SimpleControllerHandlerAdapter

Este é o adaptador de manipulador padrão registrado pelo Spring MVC. Ele lida com classes que implementam a interfaceController e é usado para encaminhar uma solicitação a um objeto controlador.

Se um aplicativo da web usa apenas controladores, não precisamos configurar nenhumHandlerAdapter, pois o framework usa essa classe como o adaptador padrão para lidar com uma solicitação.

Vamos definir uma classe de controlador simples, usando o estilo mais antigo de controlador (implementando a interfaceController):

public class SimpleController implements Controller {
    @Override
    public ModelAndView handleRequest(
      HttpServletRequest request,
      HttpServletResponse response) throws Exception {

        ModelAndView model = new ModelAndView("Greeting");
        model.addObject("message", "Dinesh Madhwal");
        return model;
    }
}

A configuração XML semelhante:


    
    
        
        
    

A classeBeanNameUrlHandlerMapping é a classe de mapeamento para este adaptador de manipulador.

Note: se um adaptador de manipulador personalizado for definido emBeanFactory,, esse adaptador não será registrado automaticamente. Portanto, precisamos defini-lo explicitamente no contexto. Se não estiver definido e tivermos definido um adaptador de manipulador personalizado, obteremos uma exceção que indica que nenhum adaptador para um manipulador está especificado.

4.2. SimpleServletHandlerAdapter

Este adaptador de manipulador permite o uso de qualquerServlet para trabalhar comDispatcherServlet para manipular a solicitação. Ele encaminha a solicitação deDispatcherServlet para a classeServlet apropriada chamando seu métodoservice().

Os beans que implementam a interfaceServlet são manipulados automaticamente por este adaptador. Não está registrado por padrão e precisamos registrá-lo como qualquer outro bean normal no arquivo de configuração deDispatcherServlet:

4.3. AnnotationMethodHandlerAdapter

Esta classe de adaptador é usada para executar os métodos que são anotados com a anotação@RequestMapping. É usado para mapear os métodos com base em métodos e caminhos HTTP.

A classe de mapeamento para este adaptador éDefaultAnnotationHandlerMapping,, que é usada para processar a anotação@RequestMapping no nível do tipo eAnnotationMethodHandlerAdaptor é usada para processar no nível do método.

Essas duas classes já estão registradas pelo framework quandoDispatcherServlet é inicializado. No entanto, se os outros adaptadores do manipulador já estiverem definidos, precisamos defini-lo também no arquivo de configuração.

Vamos definir uma classe de controlador:

@Controller
public class AnnotationHandler {
    @RequestMapping("/annotedName")
    public ModelAndView getEmployeeName() {
        ModelAndView model = new ModelAndView("Greeting");
        model.addObject("message", "Dinesh");
        return model;
    }
}

A anotação@Controller indica que esta classe desempenha o papel decontroller.

A anotação@RequestMapping mapeia o métodogetEmployeeName() para a URL/name.

Existem 2 maneiras diferentes de configurar esse adaptador, dependendo de o aplicativo usar a configuração baseada em Java ou XML. Vejamos a primeira maneira usando a configuração Java:

@ComponentScan("com.example.spring.controller")
@Configuration
@EnableWebMvc
public class ApplicationConfiguration implements WebMvcConfigurer {
    @Bean
    public InternalResourceViewResolver jspViewResolver() {
        InternalResourceViewResolver bean = new InternalResourceViewResolver();
        bean.setPrefix("/WEB-INF/");
        bean.setSuffix(".jsp");
        return bean;
    }
}

Se o aplicativo usar configuração XML, existem duas abordagens diferentes para configurar esse adaptador de manipulador no XML do contexto do aplicativo da web. Vamos dar uma olhada na primeira abordagem definida no arquivospring-servlet_AnnotationMethodHandlerAdapter.xml:


    
    
    
    
        
        
    

A tag<context:component-scan /> é usada para especificar o pacote para verificar as classescontroller.

Vamos dar uma olhada na segunda abordagem:


    
    
    
        
        
    

A tag<mvc:annotation-driven> registrará automaticamente essas duas classes com spring MVC. Este adaptador foi descontinuado no Spring 3.2 e um novo adaptador de manipulador chamadoRequestMappingHandlerAdapter foi introduzido no Spring 3.1.

4.4. RequestMappingHandlerAdapter

Esta classe de adaptador foi introduzida no Spring 3.1, descontinuando o adaptador de manipuladorAnnotationMethodHandlerAdaptor no Spring 3.2.

É usado com a classeRequestMappingHandlerMapping, queexecutes methods annotated with @RequestMapping.

ORequestMappingHandlerMapping é usado para manter o mapeamento do URI de solicitação para o manipulador. Depois que o manipulador é obtido, oDispatcherServlet despacha a solicitação para o adaptador do manipulador apropriado, que invoca ohandlerMethod().

Os mapeamentos em nível de tipo e em nível de método foram processados ​​em dois estágios diferentes na versão Spring anterior à 3.1.

O primeiro estágio era selecionar o controlador porDefaultAnnotationHandlerMappinge o segundo estágio era invocar o método real porAnnotationMethodHandlerAdapter.

Na versão 3.1 do Spring, há apenas um estágio, que envolve a identificação do controlador e qual método precisa ser chamado para processar a solicitação.

Vamos definir uma classe de controlador simples:

@Controller
public class RequestMappingHandler {

    @RequestMapping("/requestName")
    public ModelAndView getEmployeeName() {
        ModelAndView model = new ModelAndView("Greeting");
        model.addObject("message", "Madhwal");
        return model;
    }
}

Existem 2 maneiras diferentes de configurar esse adaptador, dependendo de o aplicativo usar a configuração baseada em Java ou XML.

Vejamos a primeira maneira de usar a configuração Java:

@ComponentScan("com.example.spring.controller")
@Configuration
@EnableWebMvc
public class ServletConfig implements WebMvcConfigurer {
    @Bean
    public InternalResourceViewResolver jspViewResolver() {
        InternalResourceViewResolver bean = new InternalResourceViewResolver();
        bean.setPrefix("/WEB-INF/");
        bean.setSuffix(".jsp");
        return bean;
    }
}

Se o aplicativo usar configuração XML, existem duas abordagens diferentes para configurar esse adaptador de manipulador no XML do contexto do aplicativo da web. Vamos dar uma olhada na primeira abordagem definida no arquivospring-servlet_RequestMappingHandlerAdapter.xml:


    

    

    

    
        
        
    

E aqui está a segunda abordagem:


    

    

    
        
        
    

Essa tag registrará automaticamente essas duas classes no Spring MVC.

Se precisarmos personalizarRequestMappingHandlerMapping,, precisamos remover essa tag do XML do contexto do aplicativo e configurá-lo manualmente no XML do contexto do aplicativo.

4.5. HttpRequestHandlerAdapter

Este adaptador de manipulador é usado para os manipuladores que processamHttpRequests. Ele implementa a interfaceHttpRequestHandler, que contém um único métodohandleRequest() para processar a solicitação e gerar a resposta.

O tipo de retorno deste método é nulo e não geraModelAndView tipo de retorno conforme produzido por outros adaptadores do manipulador. É basicamente usado para gerar respostas binárias e não gera uma visualização para renderizar.

5. Executando o aplicativo

Se o aplicativo for implantado emlocalhost com o número da porta8082 e a raiz de contexto forspring-mvc-handlers:

http://localhost:8082/spring-mvc-handlers/

6. Conclusão

Neste artigo, discutimos vários tipos de adaptadores de manipulador disponíveis na estrutura Spring.

A maioria dos desenvolvedores provavelmente se manterá nos padrões, mas vale a pena entender o quão flexível é a estrutura quando precisamos ir além do básico.

O código-fonte deste tutorial pode ser encontrado emGitHub project.