Краткое руководство по пружинным контроллерам
1. Вступление
В этой статье мы сосредоточимся на основной концепции Spring MVC - контроллерах.
2. обзор
Давайте начнем с шага назад и взглянем наthe concept of the Front Controller in the typical Spring Model View Controller architecture.
Вот основные обязанности, которые мы рассматриваем на очень высоком уровне:
-
Перехватывает входящие запросы
-
Преобразует полезную нагрузку запроса во внутреннюю структуру данных.
-
Отправляет данные вModel для дальнейшей обработки
-
Получает обработанные данные изModel и продвигает эти данные вView для рендеринга
Вот краткая диаграмма расхода высокого уровня вSpring MVC:
Как видите,DispatcherServlet играет рольFront Controller в архитектуре.
Диаграмма применима как к типичным контроллерам MVC, так и к контроллерам RESTful - с некоторыми небольшими отличиями (описанными ниже).
В традиционном подходе приложенияMVC не ориентированы на службы, поэтому существует View Resolver, который отображает окончательные представления на основе данных, полученных отController.
ПриложенияRESTful предназначены для обслуживания и возврата необработанных данных (обычно JSON / XML). Поскольку эти приложения не выполняют визуализацию представления, нетView Resolvers - обычно ожидается, чтоController будет отправлять данные непосредственно через HTTP-ответ.
Начнем с контроллеров в стиле MVC0.
3. Maven Зависимости
Чтобы иметь возможность работать сSpring MVC, давайте сначала разберемся с зависимостями Maven:
org.springframework
spring-webmvc
5.0.6.RELEASE
Чтобы получить последнюю версию библиотеки, посмотритеspring-webmvc on Maven Central.
4. Веб-конфигурация проекта
Теперь, прежде чем рассматривать сами контроллеры, нам сначала нужно настроить простой веб-проект и выполнить быструю настройкуServlet.
Давайте сначала посмотрим, как можно настроитьDispatcherServlet без использованияweb.xml - но вместо этого с использованием инициализатора:
public class StudentControllerConfig implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext sc) throws ServletException {
AnnotationConfigWebApplicationContext root =
new AnnotationConfigWebApplicationContext();
root.register(WebConfig.class);
root.refresh();
root.setServletContext(sc);
sc.addListener(new ContextLoaderListener(root));
DispatcherServlet dv =
new DispatcherServlet(new GenericWebApplicationContext());
ServletRegistration.Dynamic appServlet = sc.addServlet("test-mvc", dv);
appServlet.setLoadOnStartup(1);
appServlet.addMapping("/test/*");
}
}
Чтобы настроить все без XML, убедитесь, что в пути к классам естьservlet-api 3.1.0.
Вот как будет выглядетьweb.xml:
test-mvc
org.springframework.web.servlet.DispatcherServlet
1
contextConfigLocation
/WEB-INF/test-mvc.xml
Здесь мы устанавливаем свойствоcontextConfigLocation, указывающее на файлXML, используемый для загрузки контекста Spring. Если свойство отсутствует, Spring будет искать файл с именем{servlet_name}-servlet.xml.
В нашем случаеservlet_name - этоtest-mvc, поэтому в этом примереDispatcherServlet будет искать файл с именемtest-mvc-servlet.xml.
Наконец, давайте настроимDispatcherServlet и сопоставим его с конкретнымURL - чтобы закончить нашу систему на основеFront Controller здесь:
test-mvc
/test/*
Таким образом, в этом случаеDispatcherServlet будет перехватывать все запросы в шаблоне/test/*.
5. Веб-конфигурация Spring MVC
Давайте теперь посмотрим, как можно настроитьDispatcher Servlet с помощьюSpring Config:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages= {
"org.example.controller.controller",
"org.example.controller.config" })
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean =
new InternalResourceViewResolver();
bean.setPrefix("/WEB-INF/");
bean.setSuffix(".jsp");
return bean;
}
}
Теперь давайте посмотрим, как настроитьDispatcher Servlet с помощьюXML. Снимок файлаDispatcherServlet XML - файлаXML, которыйDispatcherServlet использует для загрузки пользовательскогоcontrollers и другихSpringentities, показан ниже:
/WEB-INF/
.jsp
Основываясь на этой простой конфигурации, инфраструктура, конечно, инициализирует любой компонент контроллера, найденный в пути к классам.
Обратите внимание, что мы также определяем View Resolver, отвечающий за рендеринг представления - здесь мы будем использовать SpringInternalResourceViewResolver. Ожидается, что имяview будет разрешено, что означает поиск соответствующей страницы с использованием префикса и суффикса (оба определены в конфигурацииXML).
Так, например, еслиController возвращаетview с именем «welcome”*,*, тоviewresolver попытается разрешить страницу с именем“welcome.jsp” вWEB-INF папку.
6. Контроллер MVC
Давайте не будем наконец реализовывать контроллер стиля MVC.
Обратите внимание, как мы возвращаем объектModelAndView, который содержитmodel map иview object; оба будут использоваться View Resolver для рендеринга данных:
@Controller
@RequestMapping(value = "/test")
public class TestController {
@GetMapping
public ModelAndView getTestData() {
ModelAndView mv = new ModelAndView();
mv.setViewName("welcome");
mv.getModel().put("data", "Welcome home man");
return mv;
}
}
Итак, что именно мы настроили здесь.
Сначала мы создали контроллер с именемTestController и сопоставили его с путем“/test”. В классе мы создали метод, который возвращает объектModelAndView и сопоставляется с запросомGET, поэтому любой URL-вызов, заканчивающийся на «test», будет маршрутизироватьсяDispatcherServlet к методуgetTestData вTestController.
И, конечно же, мы возвращаем объектModelAndView с некоторыми данными модели для хорошей оценки.
Объект просмотра имеет имя, установленное на «welcome». Как обсуждалось выше,View Resolver будет искать страницу в папкеWEB-INF под названием «welcome.jsp».
Ниже вы можете увидеть результат примера операцииGET:
Обратите внимание, чтоURL заканчивается на“test”. ОбразецURL равен“/test/test “.
Первый“/test” поступает от сервлета, а второй - от отображения контроллера.
7. Дополнительные зависимости Spring для REST
Давайте теперь посмотрим на контроллер RESTful. Конечно, хорошее место для начала - это дополнительные зависимости Maven, которые нам нужны для этого:
org.springframework
spring-webmvc
5.0.6.RELEASE
org.springframework
spring-web
5.0.6.RELEASE
com.fasterxml.jackson.core
jackson-databind
2.9.5
Пожалуйста, обратитесь к ссылкамjackson-core,spring-webmvc иspring-web для получения новейших версий этих зависимостей.
Jackson здесь, конечно, не является обязательным, но это, безусловно, хороший способ включить поддержку JSON. Если вы хотите глубже погрузиться в эту поддержку, взгляните наmessage converters article here.
8. REST Controller
Настройка для приложенияSpring RESTful такая же, как и для приложенияMVC, с той лишь разницей, что нет View Resolvers и нетmodel map.
API обычно просто возвращает необработанные данные обратно клиенту - обычно представленияXML иJSON - и поэтомуDispatcherServlet обходитview resolvers иreturns the data right in the HTTP response body.
Давайте посмотрим на простую реализацию контроллера RESTful:
@Controller
public class RestController {
@GetMapping(value = "/student/{studentId}")
public @ResponseBody Student getTestData(@PathVariable Integer studentId) {
Student student = new Student();
student.setName("Peter");
student.setId(studentId);
return student;
}
}
Обратите внимание на аннотацию@ResponseBody к методу, которая инструктирует Spring обходитьview resolver иessentially write out the output directly to the body of the HTTP response.
Быстрый снимок вывода показан ниже:
Приведенный выше вывод является результатом отправки запросаGET к API с ученикомid из1.
Одно небольшое примечание:the @RequestMapping annotation - одна из тех центральных аннотаций, которые вам действительно нужно изучить, чтобы использовать весь свой потенциал.
9. Spring Boot и аннотация@RestController
Аннотация@RestController из Spring Boot - это, по сути, быстрый ярлык, который избавляет нас от необходимости всегда определять@ResponseBody.
Вот предыдущий пример контроллера, использующий эту новую аннотацию:
@RestController
public class RestAnnotatedController {
@GetMapping(value = "/annotated/student/{studentId}")
public Student getData(@PathVariable Integer studentId) {
Student student = new Student();
student.setName("Peter");
student.setId(studentId);
return student;
}
}
10. Заключение
В этом руководстве мы рассмотрим основы использования контроллеров в Spring, как с точки зрения типичного приложения MVC, так и с помощью RESTful API.
Конечно, весь код в статье доступенover on GitHub.