SpringMVC: Framework para aplicaciones web en Java
SpringMVC es un framework parte del ecosistema Spring, diseñado para facilitar el desarrollo de aplicaciones web basadas en el patrón Modelo-Vista-Controlador (MVC). Su función principal es gestionar la interacción entre la capa de presentación (Vista) y la lógica de negocio (Controlador).
Conceptos de MVC
El patrón MVC separa una aplicación en tres componentes:
- Modelo: Representa los datos y la lógica de negocio. En SpringMVC, el framework no se encarga directamente de esta capa, que se implementa mediante servicios y capas de acceso a datos (DAO).
- Vista: Maneja la presentación de los datos al usuario. Se implementa con tecnologías como HTML, JSP o Thymeleaf.
- Controlador: Procesa las solicitudes del usuario, interactúa con el Modelo y decide qué Vista mostrar. En SpringMVC, se implementa como clases Java anotadas con
@Controller.
Componentes principales de SpringMVC
SpringMVC se basa en los siguientes componentes para procesar soliciutdes:
- DispatcherServlet: Servlet frontal que recibe todas las solicitudes entrantes y las enruta.
- HandlerMapping: Mapea las rutas de solicitud a los controladores apropiados.
- Controller: Componente que contiene la lógica para manejar solicitudes específicas.
- ModelAndView: Objeto que encapsula los datos (Modelo) y el nombre de la vista a renderizar.
- ViewResolver: Resuelve el nombre de la vista devuelto por el controlador a un componente de vista real (por ejemplo, un archivo HTML).
Flujo de ejecución típico
El procesamiento de una solicitud en SpringMVC sigue estos pasos:
- El usuario envía una solicitud HTTP.
- El DispatcherServlet recibe la solicitud y consulta al HandlerMapping para encontrar el controlador adecuado.
- El HandlerMapping devuelve una cadena de ejecución que incluye el controlador y posibles interceptores.
- El DispatcherServlet invoca el controlador a través de un adaptador de handler.
- El controlador procesa la solicitud, interactúa con el modelo si es necesario y devuelve un objeto
ModelAndView. - El DispatcherServlet utiliza el ViewResolver para resolver la vista basándose en el nombre devuelto.
- La vista se renderiza y se devuelve la respuesta al usuario.
Configuración inicial de un proyecto SpringMVC
Para crear un proyecto SpringMVC con Maven, se requeiren los siguientes pasos:
1. Configuración de Maven
Añadir dependencias esenciales en el archivo pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.10</version>
</dependency>
<!-- Dependencias para Thymeleaf como motor de plantillas -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
</dependencies>
2. Configuración del DispatcherServlet
En el archivo web.xml, configurar el servlet frontal:
<servlet>
<servlet-name>frontController</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>frontController</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
3. Configuración del contexto Spring
Crear un archivo de configuración Spring (por ejemplo, spring-config.xml) con:
<!-- Habilitar escaneo de componentes -->
<context:component-scan base-package="com.ejemplo.controladores" />
<!-- Configurar el motor de plantillas Thymeleaf -->
<bean id="plantillaResolver" class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/vistas/" />
<property name="suffix" value=".html" />
</bean>
<bean id="motorPlantillas" class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver" ref="plantillaResolver" />
</bean>
<bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="templateEngine" ref="motorPlantillas" />
<property name="characterEncoding" value="UTF-8" />
</bean>
Creación de un controlador básico
Un controlador se define con la anotación @Controller y métodos anotados con @RequestMapping para mapear URLs:
@Controller
@RequestMapping("/saludos")
public class GestorSaludos {
@RequestMapping("/inicio")
public String mostrarPaginaInicio() {
// Lógica de negocio
return "inicio"; // Nombre de la vista a resolver
}
}
En este ejemplo, una solicitud a /app/saludos/inicio se manejará mediante el método mostrarPaginaInicio, que devuelve el nombre de la vista "inicio" (por ejemplo, inicio.html en la carpeta configurada).
Recepción de parámetros de solicitud
SpringMVC ofrece varias formas de acceder a los parámetros enviados por el cliente:
1. Declaración directa en el método
Los parámetros se pueden declarar como argumentos del método, coincidiendo con los nombres de los campos del formulario:
@RequestMapping("/procesar")
public String manejarDatos(String nombreUsuario, String claveAcceso) {
// Usar parámetros directamente
return "resultado";
}
2. Uso de objetos de modelo
Para un conjunto grande de parámetros, se pueden encapsular en un POJO (Plain Old Java Object):
public class DatosUsuario {
private String nombre;
private String clave;
private int edad;
// Getters y setters
}
@RequestMapping("/registrar")
public String registrarUsuario(DatosUsuario datos) {
// Acceder a datos.getNombre(), etc.
return "exito";
}
Transferencia de datos a la vista
Para pasar datos desde el controlador a la vista, se utiliza el parámetro ModelMap o la anotación @ModelAttribute:
@RequestMapping("/perfil")
public String mostrarPerfil(ModelMap modelo) {
String nombreUsuario = "Ejemplo";
modelo.addAttribute("usuario", nombreUsuario);
return "perfil";
}
En la vista (por ejemplo, un archivo HTML con Thymeleaf), se accede al dato con th:text="${usuario}".
Redirecciones
Para redirigir a otra URL después de procesar una solicitud, se devuelve una cadena con el prefijo redirect::
@RequestMapping("/accion")
public String ejecutarAccion() {
// Lógica de procesamiento
return "redirect:/saludos/inicio";
}
Interceptores
Los interceptores permiten ejecutar código antes o después del manejo de una solicitud. Se implementan mediante la interfaz HandlerInterceptor:
public class InterceptorAutenticacion implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest solicitud, HttpServletResponse respuesta, Object handler) {
// Lógica de verificación
return true; // true para permitir, false para bloquear
}
}
Se configuran en el archivo de configuración Spring:
<mvc:interceptors>
<bean class="com.ejemplo.interceptores.InterceptorAutenticacion" />
</mvc:interceptors>
Gestión de sesiones
Para acceder a datos de sesión, se puede inyectar HttpSession en el método del controlador:
@RequestMapping("/login")
public String iniciarSesion(String usuario, HttpSession sesion) {
sesion.setAttribute("usuarioActual", usuario);
return "dashboard";
}
Filtros vs. Interceptores
En aplicaciones web Java, tanto filtros como interceptores se usan para interceptar solicitudes, pero tienen diferencias clave:
- Filtros: Son parte de la especificación Servlet, se configuran en
web.xmly se ejecutan antes de llegar al DispatcherServlet. Son útiles para tareas como codificación de caracteres. - Interceptores: Son parte de SpringMVC, se ejecutan después del DispatcherServlet pero antes del controlador, y ofrecen más flexibilidad en la integración con el framework.
Para establecer la codificación UTF-8 en solicitudes POST, se debe configurar un filtro de caracteres:
<filter>
<filter-name>filtroCodificacion</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filtroCodificacion</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>