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

Підтримує API , використовується для перевірки , якщо конкретний екземпляр обробника підтримується чи ні. Цей метод слід викликати спочатку перед викликом методу handle () цього інтерфейсу, щоб переконатися, чи підтримується екземпляр обробника.

Ручка API використовується для обробки конкретного запиту HTTP. Цей метод відповідає за виклик обробника, передаючи в якості параметра об'єкти HttpServletRequest та HttpServletResponse . Потім обробник виконує логіку програми і повертає об'єкт ModelAndView , який потім обробляється DispatcherServlet .

3. Залежність Мейвена

Почнемо з залежності Maven, яку потрібно додати до pom.xml :

 org.springframework spring-webmvc 5.2.8.RELEASE 

Останню версію артефакту spring-webmvc можна знайти тут.

4. Типи HandlerAdapter

4.1. SimpleControllerHandlerAdapter

Це стандартний адаптер обробника, зареєстрований Spring MVC. Він має справу з класами, що реалізують інтерфейс контролера, і використовується для пересилання запиту до об'єкта контролера.

Якщо веб-програма використовує лише контролери, тоді нам не потрібно налаштовувати будь-який HandlerAdapter, оскільки платформа використовує цей клас як адаптер за замовчуванням для обробки запиту.

Давайте визначимо простий клас контролера, використовуючи старий стиль контролера (реалізуючи інтерфейс контролера ):

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 - це клас відображення для цього адаптера обробника.

Примітка : Якщо в BeanFactory визначено спеціальний адаптер обробника , цей адаптер не реєструється автоматично. Таким чином, нам потрібно чітко визначити це в контексті. Якщо це не визначено, і ми визначили спеціальний адаптер обробника, то ми отримаємо виняток, який говорить, що адаптер для обробника не вказаний.

4.2. SimpleServletHandlerAdapter

Цей адаптер обробника дозволяє використовувати будь-який сервлет для роботи з DispatcherServlet для обробки запиту. Він пересилає запит від DispatcherServlet до відповідного класу сервлетів , викликаючи метод service () .

Файли, що реалізують інтерфейс Servlet , автоматично обробляються цим адаптером. Він не зареєстрований за замовчуванням, і нам потрібно зареєструвати його як будь-який інший звичайний компонент у файлі конфігурації 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 анотацію вказує на те, що цей клас грає роль контролера.

@RequestMapping анотацію відображає getEmployeeName () метод до URL / ім'я.

Існує 2 різні способи налаштування цього адаптера, залежно від того, використовує додаток конфігурацію на основі Java або конфігурацію на основі XML. Давайте розглянемо перший спосіб використання конфігурації Java:

@ComponentScan("com.baeldung.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 :

тег використовується для вказівки пакету для сканування класів контролерів .

Погляньмо на другий підхід:

тег автоматично реєструє ці два класи з весняним MVC. Цей адаптер був застарілий навесні 3.2, а новий адаптер обробника під назвою RequestMappingHandlerAdapter був представлений навесні 3.1.

4.4. RequestMappingHandlerAdapter

Цей клас адаптера був представлений навесні 3.1, припинивши роботу обробника адаптера AnnotationMethodHandlerAdaptor навесні 3.2.

Він використовується з класом RequestMappingHandlerMapping , який виконує методи, анотовані @RequestMapping .

RequestMappingHandlerMapping використовується для підтримки відображення запиту URI обробника. Після отримання обробника DispatcherServlet відправляє запит до відповідного адаптера обробника, який потім викликає handlerMethod ().

Зіставлення на рівні типу та рівня методу оброблялись у два різні етапи у версії Spring до версії 3.1.

Першим етапом був вибір контролера за допомогою DefaultAnnotationHandlerMapping, а другим етапом був виклик фактичного методу за допомогою AnnotationMethodHandlerAdapter .

З весняної версії 3.1 існує лише один етап, який включає ідентифікацію контролера, а також те, який метод потрібно викликати для обробки запиту.

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

@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.baeldung.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

This handler adapter is used for the handlers that process HttpRequests. It implements the HttpRequestHandler interface, which contains a single handleRequest() method for processing the request and generating the response.

The return type of this method is void and it doesn't generate ModelAndView return type as produced by other handler adapters. It's basically used to generate binary responses and it doesn't generate a view to render.

5. Running the Application

If the application is deployed on localhost with the port number 8082 and the context-root is spring-mvc-handlers:

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

6. Conclusion

У цій статті ми обговорили різні типи адаптерів обробників, доступних у Spring framework.

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

Вихідний код цього посібника можна знайти в проекті GitHub.