Spring Boot

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ícate

Model 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.

Aprende SpringBoot online

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

Spring Boot

Introducción Y Entorno

Spring Boot Starters

Spring Boot

Introducción Y Entorno

Inyección De Dependencias

Spring Boot

Introducción Y Entorno

Crear Proyecto Con Spring Initializr

Spring Boot

Introducción Y Entorno

Crear Proyecto Desde Visual Studio Code

Spring Boot

Introducción Y Entorno

Controladores Spring Mvc

Spring Boot

Spring Mvc Con Thymeleaf

Vista En Spring Mvc Con Thymeleaf

Spring Boot

Spring Mvc Con Thymeleaf

Controladores Spring Rest

Spring Boot

Spring Mvc Con Thymeleaf

Open Api Y Cómo Agregarlo En Spring Boot

Spring Boot

Spring Mvc Con Thymeleaf

Servicios En Spring

Spring Boot

Spring Mvc Con Thymeleaf

Clientes Resttemplate Y Restclient

Spring Boot

Spring Mvc Con Thymeleaf

Rxjava En Spring Web

Spring Boot

Spring Mvc Con Thymeleaf

Métodos Post En Controladores Mvc

Spring Boot

Spring Mvc Con Thymeleaf

Métodos Get En Controladores Mvc

Spring Boot

Spring Mvc Con Thymeleaf

Formularios En Spring Mvc

Spring Boot

Spring Mvc Con Thymeleaf

Crear Proyecto Con Intellij Idea

Spring Boot

Spring Mvc Con Thymeleaf

Introducción A Los Modelos Mvc

Spring Boot

Spring Mvc Con Thymeleaf

Layouts Y Fragmentos En Thymeleaf

Spring Boot

Spring Mvc Con Thymeleaf

Estilización Con Bootstrap Css

Spring Boot

Spring Mvc Con Thymeleaf

Gestión De Errores Controlleradvice

Spring Boot

Spring Mvc Con Thymeleaf

Estilización Con Tailwind Css

Spring Boot

Spring Mvc Con Thymeleaf

Introducción A Controladores Rest

Spring Boot

Spring Rest

Métodos Get En Controladores Rest

Spring Boot

Spring Rest

Métodos Post En Controladores Rest

Spring Boot

Spring Rest

Métodos Delete En Controladores Rest

Spring Boot

Spring Rest

Métodos Put Y Patch En Controladores Rest

Spring Boot

Spring Rest

Gestión De Errores Restcontrolleradvice

Spring Boot

Spring Rest

Creación De Entidades Jpa

Spring Boot

Spring Data Jpa

Asociaciones De Entidades Jpa

Spring Boot

Spring Data Jpa

Repositorios Spring Data

Spring Boot

Spring Data Jpa

Métodos Find En Repositorios

Spring Boot

Spring Data Jpa

Inserción De Datos

Spring Boot

Spring Data Jpa

Actualizar Datos De Base De Datos

Spring Boot

Spring Data Jpa

Borrar Datos De Base De Datos

Spring Boot

Spring Data Jpa

Consultas Jpql Con @Query En Spring Data Jpa

Spring Boot

Spring Data Jpa

Api Query By Example (Qbe)

Spring Boot

Spring Data Jpa

Api Specification

Spring Boot

Spring Data Jpa

Repositorios Reactivos

Spring Boot

Spring Data Jpa

Configuración Base De Datos Postgresql

Spring Boot

Spring Data Jpa

Configuración Base De Datos Mysql

Spring Boot

Spring Data Jpa

Introducción A Jpa Y Spring Data Jpa

Spring Boot

Spring Data Jpa

Configuración Base De Datos H2

Spring Boot

Spring Data Jpa

Testing Unitario De Componentes Y Servicios

Spring Boot

Testing Con Spring Test

Testing De Repositorios Spring Data Jpa

Spring Boot

Testing Con Spring Test

Testing Controladores Spring Mvc Con Thymeleaf

Spring Boot

Testing Con Spring Test

Testing Controladores Rest Con Json

Spring Boot

Testing Con Spring Test

Testing De Aplicaciones Reactivas Webflux

Spring Boot

Testing Con Spring Test

Testing De Seguridad Spring Security

Spring Boot

Testing Con Spring Test

Testing Con Apache Kafka

Spring Boot

Testing Con Spring Test

Introducción Al Testing

Spring Boot

Testing Con Spring Test

Introducción A Spring Security

Spring Boot

Seguridad Con Spring Security

Seguridad Basada En Formulario

Spring Boot

Seguridad Con Spring Security

Registro De Usuarios En Api Rest

Spring Boot

Seguridad Con Spring Security

Login De Usuarios En Api Rest

Spring Boot

Seguridad Con Spring Security

Validación Jwt En Api Rest

Spring Boot

Seguridad Con Spring Security

Autenticación Jwt Completa En Api Rest

Spring Boot

Seguridad Con Spring Security

Seguridad Jwt En Api Rest Reactiva Spring Webflux

Spring Boot

Seguridad Con Spring Security

Autenticación Y Autorización Con Anotaciones

Spring Boot

Seguridad Con Spring Security

Fundamentos De Autenticación Oauth

Spring Boot

Seguridad Con Spring Security

Autenticación Oauth Con Github

Spring Boot

Seguridad Con Spring Security

Testing Con Spring Security Test

Spring Boot

Seguridad Con Spring Security

Autenticación Oauth En Api Rest

Spring Boot

Seguridad Con Spring Security

Introducción A Spring Webflux

Spring Boot

Reactividad Webflux

Spring Data R2dbc

Spring Boot

Reactividad Webflux

Controlador Reactivo Basado En Anotaciones

Spring Boot

Reactividad Webflux

Controlador Reactivo Basado En Funciones

Spring Boot

Reactividad Webflux

Operadores Reactivos Básicos

Spring Boot

Reactividad Webflux

Operadores Reactivos Avanzados

Spring Boot

Reactividad Webflux

Cliente Reactivo Webclient

Spring Boot

Reactividad Webflux

Introducción E Instalación De Apache Kafka

Spring Boot

Mensajería Asíncrona

Crear Proyecto Con Apache Kafka

Spring Boot

Mensajería Asíncrona

Creación De Producers

Spring Boot

Mensajería Asíncrona

Creación De Consumers

Spring Boot

Mensajería Asíncrona

Kafka Streams En Spring Boot

Spring Boot

Mensajería Asíncrona

Integración Con Angular

Spring Boot

Integración Frontend

Integración Con React

Spring Boot

Integración Frontend

Integración Con Vue

Spring Boot

Integración Frontend

Accede GRATIS a SpringBoot y certifícate

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.

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.