Guía Técnica de Spring MVC: Arquitectura y Configuración

Spring MVC es un framwork diseñado para desacoplar la lógica de presentación de la lógica de negocio en aplicaciones web Java, optimizando la gestión de Servlets de manera análoga a cómo MyBatis simplifica la capa DAO o Spring Core la capa de servicios. Actualmente, se posiciona como el estándar frente a alternativas como Struts o JFinal.

Configuración Mediante Archivos XML

En el modelo tradicional, el flujo se define a través de archivos de configuración. Primero, es necesaroi definir el controlador en un archivo, por ejemplo, web-mvc-config.xml.

<!-- Definición del controlador en el contexto de Spring -->
<bean id="/loginAction" class="com.app.web.LoginController" />

El controlador debe implementar la interfaz Controller y retornar un objeto ModelAndView:

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class LoginController implements Controller {
   @Override
   public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
       ModelAndView mv = new ModelAndView();
       mv.addObject("usuarioActivo", "Admin");
       mv.setViewName("dashboard.jsp");
       return mv;
   }
}

Posteriormente, se configura el DispatcherServlet en el archivo web.xml para actuar como el front-controller de la aplicación:

<servlet>
   <servlet-name>appDispatcher</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>appDispatcher</servlet-name>
   <url-pattern>/</url-pattern>
</servlet-mapping>

Desarrollo Basado en Anotaciones

La evolución del framwork permite prescindir de la implementación forzosa de interfaces mediante el uso de anotaciones. Para habilitar esto, se debe configurar el escaneo de componentes en el XML de Spring:

<!-- Escaneo de clases anotadas -->
<context:component-scan base-package="com.app.controllers" />
<!-- Activación de controladores de anotaciones, validación y soporte JSON -->
<mvc:annotation-driven />

Uso de @Controller y @RequestMapping

Las anotaciones permiten definir rutas de acceso y el ciclo de vida del componente. Con @Scope("prototype"), se garantiza que se cree una nueva instancia por cada petición.

@Controller
@RequestMapping("/inventario")
public class ProductoController {

   @RequestMapping("/lista")
   public String listarProductos(Model modelo) {
       modelo.addAttribute("items", Arrays.asList("Laptop", "Monitor"));
       return "productos/vistas/lista"; 
   }

   @RequestMapping("/detalles")
   public String verDetalle(HttpServletRequest req) {
       req.setAttribute("msg", "Datos cargados desde Request");
       return "productos/detalle";
   }
}

Gestión de Parámetros de Entrada

Spring MVC ofrece múltiples mecanismos para capturar datos enviados por el cliente:

  • Captura Individual: Vinculación directa por nombre de parámetro.
  • Objetos POJO: Mapeo automático de campos de formulario a atributos de un objeto.
  • RESTful: Uso de @PathVariable para extraer datos de la URL.
  • JSON: Uso de @RequestBody junto con Jackson para deserializar datos.
@RequestMapping("/api/v1/auth/{rol}")
public String autenticar(
   @PathVariable String rol,
   @RequestParam("token") String jwt,
   UserDTO usuario) {
   // Lógica de procesamiento
   return "success";
}

Codificación y Seguridad de Recursos

Para evitar problemas con caracteres especiales, se recomienda el uso de un filtro de codificación en el web.xml:

<filter>
   <filter-name>encodingFilter</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>

Es una práctica estándar colocar los archivos JSP dentro del directorio /WEB-INF/. Esto impide que los usuarios accedan directamente a las vistas, forzando el paso a través del controlador.

Resolución de Vistas

El InternalResourceViewResolver automatiza la búsqueda de plantillas añadiendo prefijos y sufijos a los nombres retornados por los métodos.

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   <property name="prefix" value="/WEB-INF/vistas/" />
   <property name="suffix" value=".jsp" />
</bean>

Carga y Descarga de Archivos

Para procesar archivos, se requiere el bean multipartResolver y configurar el formulario con enctype="multipart/form-data".

@RequestMapping("/upload")
public String procesarArchivo(MultipartFile adjunto) throws IOException {
   if (!adjunto.isEmpty()) {
       File destino = new File("/storage/uploads/", adjunto.getOriginalFilename());
       adjunto.transferTo(destino);
   }
   return "status_ok";
}

Jerarquía de Contenedores

En aplicaciones complejas, Spring opera con una estructura de padre e hijo. El Contexto Padre (cargado vía ContextLoaderListener) suele contener servicios y DAOs. El Contexto Hijo (específico del DispatcherServlet) contiene controladores y resolutores de vistas. El hijo puede acceder a los beans del padre, pero no a la inversa.

Pools de Conexiones: DBCP vs C3P0

Al integrar Spring con bases de datos, la elección del pool de conexiones es crítica:

  • DBCP (Apache): Se enfoca en gestionar un número máximo de conexiones. Si se excede, las conexiones se cierran. Es conocido por su alta velocidad de ejecución.
  • C3P0: Implementa una gestión basada en el tiempo de inactividad (idle time). Desconecta automáticamente los enlaces que superan el tiempo de espera. Posee mecanismos de recuperación automática más robustos, aunque puede ser ligeramente más lento que DBCP.

Etiquetas: SpringMVC JavaEE DispatcherServlet WebFramework MVC-Architecture

Publicado el 7-15 01:28