HandlerAdapters в Spring MVC

HandlerAdapters в Spring MVC

1. обзор

В этой статье мы сосредоточимся на различных реализациях адаптеров-обработчиков, доступных в среде Spring.

2. Что такое адаптер для рук?

HandlerAdapter - это в основном интерфейс, который очень гибко упрощает обработку HTTP-запросов в Spring MVC.

Он используется вместе сHandlerMapping, который сопоставляет метод с определенным URL.

ЗатемDispatcherServlet используетHandlerAdapter для вызова этого метода. Сервлет не вызывает метод напрямую - он в основном служит мостом между собой и объектами-обработчиками, что приводит к слабой взаимосвязи.

Давайте посмотрим на различные методы, доступные в этом интерфейсе:

public interface HandlerAdapter {
    boolean supports(Object handler);

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

    long getLastModified(HttpServletRequest request, Object handler);
}

APIsupports используется для проверки, поддерживается ли конкретный экземпляр обработчика или нет. Этот метод следует вызвать сначала перед вызовом методаhandle() этого интерфейса, чтобы убедиться, поддерживается ли экземпляр обработчика или нет.

APIhandle используется для обработки определенного HTTP-запроса. Этот метод отвечает за вызов обработчика, передавая объектHttpServletRequest иHttpServletResponse в качестве параметра. Затем обработчик выполняет логику приложения и возвращает объектModelAndView, который затем обрабатываетсяDispatcherServlet.

3. Maven Dependency

Начнем с зависимости Maven, которую нужно добавить вpom.xml:


    org.springframework
    spring-webmvc
    4.3.4.RELEASE

Последнюю версию артефактаspring-webmvc можно найтиhere.

4. ТипыHandlerAdapter

4.1. SimpleControllerHandlerAdapterс

Это адаптер обработчика по умолчанию, зарегистрированный Spring MVC. Он имеет дело с классами, реализующими интерфейсController, и используется для перенаправления запроса на объект контроллера.

Если веб-приложение использует только контроллеры, нам не нужно настраиватьHandlerAdapter, поскольку платформа использует этот класс в качестве адаптера по умолчанию для обработки запроса.

Давайте определим простой класс контроллера, используя старый стиль контроллера (реализующий интерфейсController):

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;
    }
}

Подобная конфигурация XML:


    
    
        
        
    

КлассBeanNameUrlHandlerMapping является классом сопоставления для этого адаптера обработчика.

Note: Если пользовательский адаптер обработчика определен вBeanFactory,, то этот адаптер не регистрируется автоматически. Таким образом, мы должны определить это явно в контексте. Если он не определен, и мы определили настраиваемый адаптер обработчика, мы получим исключение, которое говорит, что адаптер для обработчика не указан.

4.2. SimpleServletHandlerAdapterс

Этот адаптер-обработчик позволяет использовать любойServlet для работы сDispatcherServlet для обработки запроса. Он перенаправляет запрос отDispatcherServlet к соответствующему классуServlet, вызывая его методservice().

Бины, реализующие интерфейсServlet, автоматически обрабатываются этим адаптером. Он не зарегистрирован по умолчанию, и нам нужно зарегистрировать его, как и любой другой нормальный bean-компонент, в файле конфигурацииDispatcherServlet:

4.3. AnnotationMethodHandlerAdapterс

Этот класс адаптера используется для выполнения методов, помеченных аннотацией@RequestMapping. Он используется для отображения методов на основе методов HTTP и путей HTTP.

Класс сопоставления для этого адаптера -DefaultAnnotationHandlerMapping,, который используется для обработки аннотации@RequestMapping на уровне типа, аAnnotationMethodHandlerAdaptor используется для обработки на уровне метода.

Эти два класса уже зарегистрированы структурой при инициализацииDispatcherServlet. Однако, если другие адаптеры обработчиков уже определены, мы должны определить это также в файле конфигурации.

Давайте определим класс контроллера:

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

Аннотация@Controller указывает, что этот класс выполняет рольcontroller.

Аннотация@RequestMapping отображает методgetEmployeeName() на URL/name.

Существует 2 различных способа настройки этого адаптера в зависимости от того, использует ли приложение конфигурацию на основе Java или конфигурацию на основе XML. Давайте посмотрим на первый способ с использованием конфигурации 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;
    }
}

Если приложение использует конфигурацию XML, существует два разных подхода для настройки этого адаптера обработчика в контексте XML веб-приложения. Давайте посмотрим на первый подход, определенный в файлеspring-servlet_AnnotationMethodHandlerAdapter.xml:


    
    
    
    
        
        
    

Тег<context:component-scan /> используется для указания пакета для сканирования классовcontroller.

Давайте посмотрим на второй подход:


    
    
    
        
        
    

Тег<mvc:annotation-driven> автоматически зарегистрирует эти два класса с помощью Spring MVC. Этот адаптер устарел в Spring 3.2, а новый адаптер-обработчик под названиемRequestMappingHandlerAdapter был представлен в Spring 3.1.

4.4. RequestMappingHandlerAdapterс

Этот класс адаптера был представлен в Spring 3.1, исключая адаптер-обработчикAnnotationMethodHandlerAdaptor в Spring 3.2.

Он используется с классомRequestMappingHandlerMapping, которыйexecutes methods annotated with @RequestMapping.

RequestMappingHandlerMapping используется для поддержки сопоставления URI запроса с обработчиком. Как только обработчик получен,DispatcherServlet отправляет запрос соответствующему адаптеру обработчика, который затем вызываетhandlerMethod().

Отображения уровня типа и уровня метода обрабатывались в двух разных этапах в версии Spring до версии 3.1.

Первый этап заключался в выборе контроллераDefaultAnnotationHandlerMapping, а второй этап - в вызове фактического методаAnnotationMethodHandlerAdapter.

Начиная с версии 3.1 Spring, существует только один этап, который включает в себя определение контроллера, а также того, какой метод необходимо вызвать для обработки запроса.

Давайте определим простой класс контроллера:

@Controller
public class RequestMappingHandler {

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

Существует 2 различных способа настройки этого адаптера в зависимости от того, использует ли приложение конфигурацию на основе Java или конфигурацию на основе XML.

Давайте посмотрим на первый способ использования конфигурации 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;
    }
}

Если приложение использует конфигурацию XML, существует два разных подхода для настройки этого адаптера обработчика в контексте XML веб-приложения. Давайте посмотрим на первый подход, определенный в файлеspring-servlet_RequestMappingHandlerAdapter.xml:


    

    

    

    
        
        
    

А вот второй подход:


    

    

    
        
        
    

Этот тег автоматически зарегистрирует эти два класса в Spring MVC.

Если нам нужно настроитьRequestMappingHandlerMapping,, нам нужно удалить этот тег из XML контекста приложения и вручную настроить его в XML контекста приложения.

4.5. HttpRequestHandlerAdapterс

Этот адаптер обработчика используется для обработчиков, обрабатывающихHttpRequests. Он реализует интерфейсHttpRequestHandler, который содержит единственный методhandleRequest() для обработки запроса и генерации ответа.

Тип возврата этого метода недействителен, и он не генерирует возвращаемый типModelAndView, который создается другими адаптерами обработчика. Он в основном используется для генерации двоичных ответов и не создает представление для рендеринга.

5. Запуск приложения

Если приложение развернуто наlocalhost с номером порта8082 и корневым контекстом являетсяspring-mvc-handlers:

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

6. Заключение

В этой статье мы обсудили различные типы адаптеров обработчиков, доступных в среде Spring.

Большинство разработчиков, вероятно, будут придерживаться значений по умолчанию, но стоит понять, насколько гибка структура, когда нам нужно выйти за рамки основ.

Исходный код этого руководства можно найти в папкеGitHub project.