SpringBoot
Tutorial SpringBoot: Introducción a los modelos MVC
Aprende a usar Model y ModelAndView en Spring Boot para gestionar datos y vistas en controladores MVC de forma eficiente y organizada.
Aprende SpringBoot y certifícateModel en controladores MVC
El Model es uno de los componentes fundamentales del patrón MVC en Spring Boot. Actúa como un contenedor que permite pasar datos desde el controlador hacia la vista, facilitando la comunicación entre la lógica de negocio y la presentación.
En Spring Boot, el Model se representa mediante la interfaz Model
, que proporciona métodos para agregar atributos que posteriormente estarán disponibles en las plantillas de vista. Este mecanismo permite separar claramente la lógica del controlador de la presentación, manteniendo el código organizado y fácil de mantener.
Uso básico del Model
Para utilizar el Model en un controlador, simplemente lo declaramos como parámetro en nuestros métodos de manejo de peticiones. Spring Boot se encarga automáticamente de inyectar una instancia del Model:
@Controller
public class ProductoController {
@GetMapping("/producto")
public String mostrarProducto(Model model) {
model.addAttribute("nombre", "Laptop Gaming");
model.addAttribute("precio", 899.99);
return "producto";
}
}
En este ejemplo, agregamos dos atributos al Model: nombre
y precio
. Estos datos estarán disponibles en la vista producto.html
para ser mostrados al usuario.
Agregando objetos complejos al Model
El Model no se limita a tipos primitivos. Podemos agregar objetos complejos, listas y cualquier tipo de dato que necesitemos en la vista:
@Controller
public class UsuarioController {
@GetMapping("/perfil")
public String mostrarPerfil(Model model) {
Usuario usuario = new Usuario();
usuario.setNombre("Ana García");
usuario.setEmail("ana@ejemplo.com");
usuario.setEdad(28);
model.addAttribute("usuario", usuario);
return "perfil";
}
}
Trabajando con listas en el Model
Frecuentemente necesitamos pasar colecciones de datos a nuestras vistas. El Model maneja esto de forma natural:
@Controller
public class TiendaController {
@GetMapping("/productos")
public String listarProductos(Model model) {
List<String> productos = Arrays.asList(
"Smartphone",
"Tablet",
"Auriculares",
"Cargador"
);
model.addAttribute("listaProductos", productos);
model.addAttribute("titulo", "Catálogo de Productos");
return "catalogo";
}
}
Múltiples atributos en el Model
Un controlador puede agregar múltiples atributos al Model en una sola petición. Esto es útil cuando la vista necesita mostrar información variada:
@Controller
public class DashboardController {
@GetMapping("/dashboard")
public String mostrarDashboard(Model model) {
// Información del usuario
model.addAttribute("nombreUsuario", "Carlos Ruiz");
// Estadísticas
model.addAttribute("ventasHoy", 15);
model.addAttribute("ventasMes", 342);
// Lista de tareas pendientes
List<String> tareas = Arrays.asList(
"Revisar inventario",
"Actualizar precios",
"Contactar proveedores"
);
model.addAttribute("tareasPendientes", tareas);
return "dashboard";
}
}
Reutilización de datos del Model
El Model permite reutilizar datos entre diferentes métodos del mismo controlador mediante métodos anotados con @ModelAttribute
. Estos métodos se ejecutan antes de cada petición:
@Controller
public class BaseController {
@ModelAttribute
public void datosComunes(Model model) {
model.addAttribute("nombreApp", "Mi Aplicación");
model.addAttribute("version", "1.0");
}
@GetMapping("/inicio")
public String inicio(Model model) {
model.addAttribute("mensaje", "Bienvenido");
return "inicio";
}
@GetMapping("/acerca")
public String acerca(Model model) {
model.addAttribute("descripcion", "Aplicación de ejemplo");
return "acerca";
}
}
En este ejemplo, tanto la vista inicio
como acerca
tendrán acceso a los atributos nombreApp
y version
, además de sus atributos específicos.
Validación de datos con Model
El Model también facilita el manejo de formularios y validaciones. Cuando hay errores de validación, podemos agregar mensajes informativos:
@Controller
public class ContactoController {
@PostMapping("/contacto")
public String procesarContacto(@RequestParam String email,
@RequestParam String mensaje,
Model model) {
if (email.isEmpty() || !email.contains("@")) {
model.addAttribute("error", "Email inválido");
model.addAttribute("emailAnterior", email);
model.addAttribute("mensajeAnterior", mensaje);
return "contacto";
}
model.addAttribute("exito", "Mensaje enviado correctamente");
return "confirmacion";
}
}
El Model en Spring Boot proporciona una forma limpia y eficiente de pasar datos desde los controladores hacia las vistas, manteniendo la separación de responsabilidades que caracteriza al patrón MVC. Su simplicidad de uso y flexibilidad lo convierten en una herramienta esencial para el desarrollo de aplicaciones web.
ModelAndView en controladores MVC
ModelAndView es una alternativa al uso separado de Model y String que combina tanto los datos como la vista en un único objeto. Esta clase de Spring Boot encapsula el modelo de datos y el nombre de la vista, proporcionando una forma más compacta de manejar la respuesta del controlador.
A diferencia del enfoque tradicional donde devolvemos un String con el nombre de la vista y pasamos datos mediante el Model, ModelAndView nos permite crear un objeto que contiene toda la información necesaria para renderizar la respuesta.
Creación básica de ModelAndView
Para utilizar ModelAndView, creamos una instancia y configuramos tanto la vista como los datos que queremos enviar:
@Controller
public class EventoController {
@GetMapping("/evento")
public ModelAndView mostrarEvento() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("evento");
modelAndView.addObject("titulo", "Conferencia de Tecnología");
modelAndView.addObject("fecha", "15 de Marzo");
return modelAndView;
}
}
Constructor con vista y datos
ModelAndView ofrece constructores convenientes que permiten especificar la vista y agregar datos en una sola línea:
@Controller
public class NoticiasController {
@GetMapping("/noticia/{id}")
public ModelAndView verNoticia(@PathVariable int id) {
ModelAndView mv = new ModelAndView("noticia");
mv.addObject("id", id);
mv.addObject("titulo", "Nuevas funcionalidades en Spring Boot");
mv.addObject("autor", "Equipo de Desarrollo");
return mv;
}
}
Agregando múltiples objetos
Al igual que con Model, podemos agregar diversos tipos de datos al ModelAndView, incluyendo objetos complejos y colecciones:
@Controller
public class BibliotecaController {
@GetMapping("/biblioteca")
public ModelAndView mostrarBiblioteca() {
List<String> libros = Arrays.asList(
"Clean Code",
"Spring in Action",
"Java: The Complete Reference"
);
Map<String, Object> estadisticas = new HashMap<>();
estadisticas.put("totalLibros", 150);
estadisticas.put("librosDisponibles", 127);
ModelAndView mv = new ModelAndView("biblioteca");
mv.addObject("libros", libros);
mv.addObject("stats", estadisticas);
mv.addObject("bibliotecario", "María López");
return mv;
}
}
Manejo condicional de vistas
Una ventaja significativa de ModelAndView es la capacidad de cambiar dinámicamente la vista basándose en condiciones específicas:
@Controller
public class AccesoController {
@GetMapping("/panel")
public ModelAndView accederPanel(@RequestParam(required = false) String token) {
ModelAndView mv = new ModelAndView();
if (token != null && token.equals("admin123")) {
mv.setViewName("panel-admin");
mv.addObject("permisos", "administrador");
mv.addObject("mensaje", "Acceso concedido");
} else {
mv.setViewName("acceso-denegado");
mv.addObject("error", "Token inválido o faltante");
}
return mv;
}
}
Combinando con formularios
ModelAndView resulta especialmente útil en el procesamiento de formularios, donde necesitamos manejar tanto datos de entrada como respuestas:
@Controller
public class RegistroController {
@PostMapping("/registro")
public ModelAndView procesarRegistro(@RequestParam String nombre,
@RequestParam String email) {
ModelAndView mv = new ModelAndView();
if (nombre.length() < 2) {
mv.setViewName("registro");
mv.addObject("errorNombre", "El nombre debe tener al menos 2 caracteres");
mv.addObject("emailPrevio", email);
return mv;
}
// Simular guardado exitoso
mv.setViewName("bienvenida");
mv.addObject("usuarioNombre", nombre);
mv.addObject("fechaRegistro", LocalDate.now());
return mv;
}
}
Redireccionamiento con ModelAndView
ModelAndView también permite realizar redirecciones utilizando el prefijo "redirect:":
@Controller
public class CompraController {
@PostMapping("/comprar")
public ModelAndView procesarCompra(@RequestParam String producto) {
// Procesar la compra
boolean compraExitosa = true; // Simulación
if (compraExitosa) {
ModelAndView mv = new ModelAndView("redirect:/confirmacion");
return mv;
} else {
ModelAndView mv = new ModelAndView("error-compra");
mv.addObject("producto", producto);
mv.addObject("mensaje", "No se pudo procesar la compra");
return mv;
}
}
}
Cuándo usar ModelAndView vs Model
ModelAndView es especialmente útil cuando:
- Necesitas lógica condicional para determinar qué vista mostrar
- Quieres encapsular toda la información de respuesta en un solo objeto
- Trabajas con redirecciones dinámicas basadas en condiciones
- Prefieres un enfoque más orientado a objetos para manejar las respuestas
@Controller
public class ReporteController {
@GetMapping("/reporte")
public ModelAndView generarReporte(@RequestParam String tipo) {
ModelAndView mv = new ModelAndView();
switch (tipo.toLowerCase()) {
case "ventas":
mv.setViewName("reporte-ventas");
mv.addObject("datos", obtenerDatosVentas());
break;
case "usuarios":
mv.setViewName("reporte-usuarios");
mv.addObject("datos", obtenerDatosUsuarios());
break;
default:
mv.setViewName("error");
mv.addObject("mensaje", "Tipo de reporte no válido");
}
return mv;
}
private List<String> obtenerDatosVentas() {
return Arrays.asList("Venta 1", "Venta 2", "Venta 3");
}
private List<String> obtenerDatosUsuarios() {
return Arrays.asList("Usuario 1", "Usuario 2", "Usuario 3");
}
}
ModelAndView proporciona una alternativa elegante al uso separado de Model y String, especialmente útil cuando necesitamos mayor control sobre la selección de vistas o cuando preferimos un enfoque más cohesivo para manejar las respuestas del controlador.
Otras lecciones de SpringBoot
Accede a todas las lecciones de SpringBoot y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Spring Boot
Introducción Y Entorno
Spring Boot Starters
Introducción Y Entorno
Inyección De Dependencias
Introducción Y Entorno
Crear Proyecto Con Spring Initializr
Introducción Y Entorno
Crear Proyecto Desde Visual Studio Code
Introducción Y Entorno
Controladores Spring Mvc
Spring Mvc Con Thymeleaf
Vista En Spring Mvc Con Thymeleaf
Spring Mvc Con Thymeleaf
Controladores Spring Rest
Spring Mvc Con Thymeleaf
Open Api Y Cómo Agregarlo En Spring Boot
Spring Mvc Con Thymeleaf
Servicios En Spring
Spring Mvc Con Thymeleaf
Clientes Resttemplate Y Restclient
Spring Mvc Con Thymeleaf
Rxjava En Spring Web
Spring Mvc Con Thymeleaf
Métodos Post En Controladores Mvc
Spring Mvc Con Thymeleaf
Métodos Get En Controladores Mvc
Spring Mvc Con Thymeleaf
Formularios En Spring Mvc
Spring Mvc Con Thymeleaf
Crear Proyecto Con Intellij Idea
Spring Mvc Con Thymeleaf
Introducción A Los Modelos Mvc
Spring Mvc Con Thymeleaf
Layouts Y Fragmentos En Thymeleaf
Spring Mvc Con Thymeleaf
Estilización Con Bootstrap Css
Spring Mvc Con Thymeleaf
Gestión De Errores Controlleradvice
Spring Mvc Con Thymeleaf
Estilización Con Tailwind Css
Spring Mvc Con Thymeleaf
Introducción A Controladores Rest
Spring Rest
Métodos Get En Controladores Rest
Spring Rest
Métodos Post En Controladores Rest
Spring Rest
Métodos Delete En Controladores Rest
Spring Rest
Métodos Put Y Patch En Controladores Rest
Spring Rest
Gestión De Errores Restcontrolleradvice
Spring Rest
Creación De Entidades Jpa
Spring Data Jpa
Asociaciones De Entidades Jpa
Spring Data Jpa
Repositorios Spring Data
Spring Data Jpa
Métodos Find En Repositorios
Spring Data Jpa
Inserción De Datos
Spring Data Jpa
Actualizar Datos De Base De Datos
Spring Data Jpa
Borrar Datos De Base De Datos
Spring Data Jpa
Consultas Jpql Con @Query En Spring Data Jpa
Spring Data Jpa
Api Query By Example (Qbe)
Spring Data Jpa
Api Specification
Spring Data Jpa
Repositorios Reactivos
Spring Data Jpa
Configuración Base De Datos Postgresql
Spring Data Jpa
Configuración Base De Datos Mysql
Spring Data Jpa
Introducción A Jpa Y Spring Data Jpa
Spring Data Jpa
Configuración Base De Datos H2
Spring Data Jpa
Testing Unitario De Componentes Y Servicios
Testing Con Spring Test
Testing De Repositorios Spring Data Jpa
Testing Con Spring Test
Testing Controladores Spring Mvc Con Thymeleaf
Testing Con Spring Test
Testing Controladores Rest Con Json
Testing Con Spring Test
Testing De Aplicaciones Reactivas Webflux
Testing Con Spring Test
Testing De Seguridad Spring Security
Testing Con Spring Test
Testing Con Apache Kafka
Testing Con Spring Test
Introducción Al Testing
Testing Con Spring Test
Introducción A Spring Security
Seguridad Con Spring Security
Seguridad Basada En Formulario
Seguridad Con Spring Security
Registro De Usuarios En Api Rest
Seguridad Con Spring Security
Login De Usuarios En Api Rest
Seguridad Con Spring Security
Validación Jwt En Api Rest
Seguridad Con Spring Security
Autenticación Jwt Completa En Api Rest
Seguridad Con Spring Security
Seguridad Jwt En Api Rest Reactiva Spring Webflux
Seguridad Con Spring Security
Autenticación Y Autorización Con Anotaciones
Seguridad Con Spring Security
Fundamentos De Autenticación Oauth
Seguridad Con Spring Security
Autenticación Oauth Con Github
Seguridad Con Spring Security
Testing Con Spring Security Test
Seguridad Con Spring Security
Autenticación Oauth En Api Rest
Seguridad Con Spring Security
Introducción A Spring Webflux
Reactividad Webflux
Spring Data R2dbc
Reactividad Webflux
Controlador Reactivo Basado En Anotaciones
Reactividad Webflux
Controlador Reactivo Basado En Funciones
Reactividad Webflux
Operadores Reactivos Básicos
Reactividad Webflux
Operadores Reactivos Avanzados
Reactividad Webflux
Cliente Reactivo Webclient
Reactividad Webflux
Introducción E Instalación De Apache Kafka
Mensajería Asíncrona
Crear Proyecto Con Apache Kafka
Mensajería Asíncrona
Creación De Producers
Mensajería Asíncrona
Creación De Consumers
Mensajería Asíncrona
Kafka Streams En Spring Boot
Mensajería Asíncrona
Integración Con Angular
Integración Frontend
Integración Con React
Integración Frontend
Integración Con Vue
Integración Frontend
Ejercicios de programación de SpringBoot
Evalúa tus conocimientos de esta lección Introducción a los modelos MVC con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Crear entidades JPA
Controladores Spring MVC
Asociaciones de entidades JPA
Creación de entidades
Reto servicio PedidoService
Reto controlador REST
Consultas JPQL
Reto test controlador REST
Anotaciones JPA
Relación ManyToOne con Tarea y Proyecto
CRUD Customers Spring MVC + Spring Data JPA
Backend API REST con Spring Boot
Filtrar categorías por nombre
Reto controlador MVC Categoría
Entidad y repositorio
Métodos derivados y consultas JPQL en repositorios
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el papel del Model en el patrón MVC para pasar datos desde el controlador a la vista.
- Aprender a agregar atributos simples y complejos al Model.
- Entender cómo reutilizar datos comunes con @ModelAttribute.
- Conocer la clase ModelAndView como alternativa para encapsular datos y vista.
- Saber cuándo y cómo usar ModelAndView para lógica condicional y redirecciones.