Empecemos con una pequeña analogía para entender mejor la esencia de Spring MVC. Comparemos Spring MVC con compilar y ejecutar un programa:
- Modelo — es el compilador, que procesa el código fuente. Aplica la lógica, comprueba la sintaxis, optimiza y crea el código ejecutable. El compilador no se preocupa por cómo se mostrará el programa: se centra en procesar los datos correctamente.
- Controlador — es el sistema operativo. Recibe las órdenes del usuario, las dirige a los procesos adecuados, gestiona la memoria y los recursos, y coordina el trabajo de todos los componentes.
- Vista — es la interfaz gráfica del programa. Toma los datos procesados y se los muestra al usuario de forma comprensible — a través de ventanas, botones, formularios. Esta arquitectura, igual que Spring MVC, separa el procesamiento de datos, el control y la presentación en componentes distintos, haciendo el código más organizado y mantenible. Spring MVC implementa este patrón separando responsabilidades entre estos componentes. Vamos a ver cada uno de ellos en detalle.
Controladores: directores de las peticiones
Los controladores son el corazón de Spring MVC. Reciben peticiones HTTP, las procesan y devuelven el resultado. Son como directores que gestionan la interacción entre el modelo y la vista.
Creación de un controlador
Los controladores en Spring se marcan con la anotación @Controller. Aquí tienes un ejemplo de un controlador muy básico:
@Controller
public class HelloController {
@GetMapping("/hello")
public String sayHello(Model model) {
model.addAttribute("message", "¡Hola, Spring MVC!");
return "hello"; // Devuelve el nombre de la vista
}
}
¿Cómo funciona esto?
- Cuando el usuario abre la ruta
/hello, esa petición la intercepta el controlador. - El controlador añade datos al objeto
Modely devuelve el nombre de la vistahello. - La vista asociada al nombre
helloserá procesada y mostrada.
Tipos de controladores
- Controladores clásicos: usan la anotación
@Controller. Funcionan en conjunto con vistas. - Controladores REST: usan
@RestController, están optimizados para trabajar con REST API y devuelven JSON o XML, no páginas HTML.
Ejemplo de controlador REST:
@RestController
public class ApiController {
@GetMapping("/api/greeting")
public String getGreeting() {
return "¡Hola desde REST API!";
}
}
vamos a estudiar más a fondo los controladores REST en temas siguientes. Por ahora nos vamos a centrar en el clásico @Controller.
Modelos: transferencia de datos
El modelo en Spring MVC se usa para almacenar los datos que se pasan del controlador a la vista. La tarea principal del modelo es ser un "contenedor" de datos.
Veamos un ejemplo:
@Controller
public class UserController {
@GetMapping("/user")
public String getUser(Model model) {
model.addAttribute("username", "John Doe");
return "user"; // Nombre de la vista
}
}
El objeto Model está disponible en los métodos del controlador y permite añadir pares "clave-valor". Esos pares luego estarán accesibles en la vista.
¿Por qué el modelo es tan importante?
Imagínate que sin modelo el camarero (el controlador) tuviera que preparar los platos (los datos) por sí mismo. Eso rompe el principio de separación de responsabilidades, complica el código y al final el camarero acabaría hecho un lío.
El modelo permite separar claramente:
- La lógica de procesamiento de datos (modelo).
- La lógica de su presentación (vista).
- La lógica de enrutamiento de peticiones (controlador).
Vistas: la estética en el navegador
La vista es el resultado final del trabajo de tu aplicación que el usuario ve en el navegador. Spring MVC soporta varias tecnologías de vistas:
- JSP (Java Server Pages)
- Thymeleaf (recomendado como motor de plantillas moderno)
- FreeMarker
- Mustache
Nos vamos a centrar en Thymeleaf, ya que se usa mucho con Spring Boot.
Conectar Thymeleaf
Para usar Thymeleaf, añade su dependencia en tu pom.xml (si trabajas con Maven):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Después crea el archivo de vista hello.html en el directorio src/main/resources/templates:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<h1 th:text="'Mensaje: ' + ${message}"></h1>
</body>
</html>
Fíjate en el atributo th:text. Es la sintaxis especial de Thymeleaf para sacar datos del modelo.
Cuando el usuario abre /hello, Spring MVC renderiza esa vista, y en el navegador se mostrará: Mensaje: ¡Hola, Spring MVC!
Interacción entre componentes
Vamos a unir todo. Así es como se ve el ciclo de procesamiento de una petición en Spring MVC:
- El usuario envía una petición HTTP (por ejemplo, abre
/hello). - La petición llega al controlador
HelloController, que la procesa. - El controlador añade los datos necesarios al modelo.
- El controlador devuelve el nombre de la vista que debe mostrarse.
- Spring MVC encuentra el archivo de la vista correspondiente en la carpeta
templates(o en otra carpeta configurada). - Thymeleaf renderiza el HTML con los datos del modelo, y el resultado se envía al usuario.
Práctica: Crear una aplicación MVC básica
Paso 1: Creamos un nuevo controlador
@Controller
public class ProductController {
@GetMapping("/product")
public String getProduct(Model model) {
model.addAttribute("name", "Portátil");
model.addAttribute("price", 75000);
return "product";
}
}
Paso 2: Crea el archivo product.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product</title>
</head>
<body>
<h1>Producto: <span th:text="${name}"></span></h1>
<p>Precio: <span th:text="${price}"></span> ₽</p>
</body>
</html>
Paso 3: Ejecutamos la aplicación
Abre el navegador, ve a http://localhost:8080/product y verás la página generada.
¿Qué problemas te puedes encontrar?
- Dependencias faltantes. Si olvidas añadir Thymeleaf en las dependencias, Spring MVC no encontrará tus vistas y obtendrás
TemplateNotFoundException. - Error al añadir al modelo. Si intentas meter en el modelo un objeto que no es serializable (por ejemplo, no has sobrescrito
toStringo usas clases internas), eso puede causar problemas. - Nombre de la vista incorrecto. Si devuelves el nombre de una vista que no existe en la carpeta
templates, Spring MVC lanzaráTemplateNotFoundException.
MVC — es importante
Spring MVC juega un papel clave para crear aplicaciones web escalables. La separación en controladores, modelos y vistas hace el código más mantenible y claro. Puedes cambiar una vista sin tocar la lógica de negocio, o añadir nueva funcionalidad sin miedo a "romper" lo que ya funciona.
Las habilidades con la arquitectura MVC te servirán no solo en el código, sino también en las entrevistas. Casi todas las entrevistas para un puesto de desarrollador Java incluyen preguntas sobre los principios MVC y su implementación en Spring.
GO TO FULL VERSION