Кратко ръководство за пружинни контролери

1. Въведение

В тази статия ще се съсредоточим върху основната концепция в Spring MVC - Controllers.

2. Общ преглед

Нека започнем, като направим крачка назад и да разгледаме концепцията за предния контролер в типичната архитектура на Spring Model View Controller .

На много високо ниво, ето основните отговорности, които разглеждаме:

  • Прихваща входящи заявки
  • Преобразува полезния товар на заявката във вътрешната структура на данните
  • Изпраща данните на Model за по-нататъшна обработка
  • Получава обработени данни от модела и ги авансира в изгледа за изобразяване

Ето бърза диаграма за потока с високо ниво в Spring MVC :

Както можете да видите, DispatcherServlet играе ролята на предния контролер в архитектурата.

Диаграмата е приложима както за типични MVC контролери, така и за контролери RESTful - с някои малки разлики (описани по-долу).

В традиционния подход приложенията на MVC не са ориентирани към услуги, следователно има V iew Resolver, който прави окончателни изгледи въз основа на данни, получени от контролер .

Приложенията RESTful са проектирани да бъдат ориентирани към услуги и да връщат сурови данни (обикновено JSON / XML). Тъй като тези приложения не извършват никакво визуализиране на изгледи, няма разделители за преглед - обикновено се очаква контролерът да изпраща данни директно чрез HTTP отговора.

Нека започнем с контролерите в стил MVC0.

3. Зависимости на Maven

За да можем да работим с Spring MVC , нека първо да се справим със зависимостите на Maven:

 org.springframework spring-webmvc 5.0.6.RELEASE 

За да получите най-новата версия на библиотеката, погледнете spring-webmvc в 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 Web Config

Нека сега разгледаме как Dispatch Servlet може да бъде настроен чрез Spring Config :

@Configuration @EnableWebMvc @ComponentScan(basePackages= { "com.baeldung.controller.controller", "com.baeldung.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; } }

Нека сега разгледаме настройката на диспечерския сървлет с помощта на XML . Снимка на XML файла DispatcherServlet - XML файлът, който DispatcherServlet използва за зареждане на потребителски контролери и други пролетни обекти, е показан по-долу:

    /WEB-INF/   .jsp  

Въз основа на тази проста конфигурация, рамката, разбира се, ще инициализира всеки компонент на контролер, който ще намери в пътя на класа.

Забележете, че ние също така дефинираме View Resolver, отговорен за визуализацията на изгледа - ние ще използваме Spring's InternalResourceViewResolver тук. Това очаква да бъде разрешено име на изглед , което означава да се намери съответна страница с помощта на префикс и суфикс (и двата дефинирани в XML конфигурацията).

Така например, ако контролерът върне изглед с име „ добре дошъл“ , преобразувателят на изгледа ще се опита да разреши страница, наречена „welcome.jsp“ в папката WEB-INF .

6. Контролерът на MVC

Нека сега най-накрая да приложим контролера за стил MVC.

Забележете как връщаме обект ModelAndView - който съдържа карта на модел и обект на изглед ; и двете ще бъдат използвани от V iew 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 .

And of course we're returning the ModelAndView object with some model data for good measure.

The view object has a name set to “welcome“. As discussed above, the View Resolver will search for a page in the WEB-INF folder called “welcome.jsp“.

Below you can see the result of an example GET operation:

Note that the URL ends with “test”. The pattern of the URL is “/test/test“.

The first “/test” comes from the Servlet, and the second one comes from the mapping of the controller.

7. More Spring Dependencies for REST

Let's now start looking at a RESTful controller. Of course, a good place to start is the extra Maven dependencies we need for it:

  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   

Please refer to jackson-core, spring-webmvc and spring-web links for the newest versions of those dependencies.

Jackson is of course not mandatory here, but it's certainly a good way to enable JSON support. If you're interested to dive deeper into that support, have a look at the message converters article here.

8. The REST Controller

The setup for a Spring RESTful application is the same as the one for the MVC application with the only difference being that there is no View Resolvers and no model map.

The API will generally simply return raw data back to the client – XML and JSON representations usually – and so the DispatcherServlet bypasses the view resolvers and returns the data right in the HTTP response body.

Let's have a look at a simple RESTful controller implementation:

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

Note the @ResponseBody annotation on the method – which instructs Spring to bypass the view resolver and essentially write out the output directly to the body of the HTTP response.

A quick snapshot of the output is displayed below:

The above output is a result of sending the GET request to the API with the student id of 1.

One quick note here is – the @RequestMapping annotation is one of those central annotations that you'll really have to explore in order to use to its full potential.

9. Spring Boot and the @RestController Annotation

The @RestController annotation from Spring Boot is basically a quick shortcut that saves us from always having to define @ResponseBody.

Here's the previous example controller using this new annotation:

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

В това ръководство ние изследваме основите на използването на контролери през пролетта, както от гледна точка на типично MVC приложение, така и на RESTful API.

Разбира се, целият код в статията е достъпен в GitHub.