Guía rápida de controladores de resorte

1. Introducción

En este artículo nos centraremos en un concepto central en Spring MVC: Controladores.

2. Resumen

Comencemos por dar un paso atrás y echar un vistazo al concepto de controlador frontal en la arquitectura típica de Spring Model View Controller .

En un nivel muy alto, estas son las principales responsabilidades que estamos analizando:

  • Intercepta solicitudes entrantes
  • Convierte la carga útil de la solicitud en la estructura interna de los datos.
  • Envía los datos al modelo para su posterior procesamiento.
  • Obtiene datos procesados ​​del modelo y avanza esos datos a la vista para su representación

Aquí hay un diagrama rápido para el flujo de alto nivel en Spring MVC :

Como puede ver, DispatcherServlet juega el papel de Front Controller en la arquitectura.

El diagrama es aplicable tanto a los controladores MVC típicos como a los controladores RESTful, con algunas pequeñas diferencias (que se describen a continuación).

En el enfoque tradicional, las aplicaciones MVC no están orientadas a servicios, por lo tanto, existe un Resolver de visualización que genera vistas finales basadas en los datos recibidos de un controlador .

Las aplicaciones RESTful están diseñadas para estar orientadas a servicios y devolver datos sin procesar (JSON / XML típicamente). Dado que estas aplicaciones no hacen ningún renderizado de vistas, no hay Resolutores de Vistas ; generalmente se espera que el controlador envíe datos directamente a través de la respuesta HTTP.

Comencemos con los controladores estilo MVC0.

3. Dependencias de Maven

Para poder trabajar con Spring MVC , primero tratemos con las dependencias de Maven:

 org.springframework spring-webmvc 5.0.6.RELEASE 

Para obtener la última versión de la biblioteca, eche un vistazo a spring-webmvc en Maven Central.

4. Project Web Config

Ahora, antes de mirar los controladores en sí, primero debemos configurar un proyecto web simple y hacer una configuración rápida de Servlet .

Veamos primero cómo se puede configurar DispatcherServlet sin usar web.xml , sino usando un inicializador:

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/*"); } }

Para configurar las cosas sin XML, asegúrese de tener servlet-api 3.1.0 en su classpath.

Así es como se vería web.xml :

 test-mvc  org.springframework.web.servlet.DispatcherServlet  1  contextConfigLocation /WEB-INF/test-mvc.xml   

Estamos configurando la propiedad contextConfigLocation aquí, apuntando al archivo XML utilizado para cargar el contexto Spring. Si la propiedad no está allí, Spring buscará un archivo llamado {servlet_name} -servlet.xml .

En nuestro caso, servlet_name es test-mvc y, por tanto, en este ejemplo, DispatcherServlet buscaría un archivo llamado test-mvc-servlet.xml .

Finalmente, configuremos DispatcherServlet y mapeémoslo a una URL en particular , para finalizar nuestro sistema basado en Front Controller aquí:

 test-mvc /test/* 

Por lo tanto, en este caso, DispatcherServlet interceptaría todas las solicitudes dentro del patrón / prueba / * .

5. Configuración web Spring MVC

Veamos ahora cómo se puede configurar Dispatcher Servlet usando 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; } }

Veamos ahora cómo configurar Dispatcher Servlet usando XML . A continuación, se muestra una instantánea del archivo XML DispatcherServlet : el archivo XML que usa DispatcherServlet para cargar controladores personalizados y otras entidades Spring :

    /WEB-INF/   .jsp  

Basado en esta configuración simple, el marco, por supuesto, inicializará cualquier bean controlador que encuentre en el classpath.

Tenga en cuenta que también estamos definiendo View Resolver, responsable de la representación de la vista; aquí usaremos InternalResourceViewResolver de Spring . Esto espera que se resuelva el nombre de una vista , lo que significa buscar la página correspondiente mediante el uso de prefijo y sufijo (ambos definidos en la configuración XML ).

Así por ejemplo, si el controlador devuelve una vista llamada “ bienvenida” , el punto de vista del resolver intentará resolver una página llamada “welcome.jsp” en el WEB-INF carpeta.

6. El controlador MVC

Implementemos ahora finalmente el controlador de estilo MVC.

Observe cómo estamos devolviendo un objeto ModelAndView , que contiene un mapa modelo y un objeto de vista ; Ambos serán utilizados por V iew Resolver para la representación de datos:

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

Entonces, ¿qué hicimos exactamente aquí?

Primero, creamos un controlador llamado TestController y lo asignamos a la ruta "/ test" . En la clase, hemos creado un método que devuelve un objeto ModelAndView y se asigna a una solicitud GET, por lo que cualquier llamada URL que termine con " test " sería enrutada por DispatcherServlet al método getTestData en TestController .

Y, por supuesto, estamos devolviendo el objeto ModelAndView con algunos datos del modelo por si acaso .

El objeto de vista tiene un nombre establecido en " bienvenido ". Como se mencionó anteriormente, View Resolver buscará una página en la carpeta WEB-INF llamada " welcome.jsp ".

A continuación, puede ver el resultado de una operación GET de ejemplo :

Tenga en cuenta que la URL termina con "prueba" . El patrón de la URL es "/ test / test ".

El primer "/ test" proviene del Servlet, y el segundo proviene del mapeo del controlador.

7. Más dependencias de Spring para REST

Comencemos ahora a mirar un controlador RESTful. Por supuesto, un buen lugar para comenzar son las dependencias adicionales de Maven que necesitamos para ello:

  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   

Consulte los enlaces jackson-core, spring-webmvc y spring-web para conocer las versiones más recientes de esas dependencias.

Jackson, por supuesto, no es obligatorio aquí, pero ciertamente es una buena manera de habilitar el soporte JSON. Si está interesado en profundizar en ese soporte, eche un vistazo al artículo sobre convertidores de mensajes aquí.

8. El controlador REST

La configuración de una aplicación Spring RESTful es la misma que la de la aplicación MVC con la única diferencia de que no hay V iew Resolvers ni mapa de modelo.

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

En esta guía, exploramos los conceptos básicos del uso de controladores en Spring, tanto desde el punto de vista de una aplicación MVC típica como desde una API RESTful.

Por supuesto, todo el código del artículo está disponible en GitHub.