Manejo de Excepciones Globales en Spring MVC

Enfoque para el Manejo de Excepciones

Las excepciones en un sistema se clasifican en dos tipos: excepciones anticipadas y excepciones en tiempo de ejecución (RuntimeException). Las primeras se manejan mediante captura para obtener información del error, mientras que las segundas se minimizan siguiendo buenas prácticas de desarrollo y pruebas.

En una aplicación Spring MVC, las capas DAO, servicio y controlador propagan excepciones usando throws Exception. El controlador frontal de Spring MVC las delega a un manejador global de excepciones, como se ilustra conceptualmente:

Spring MVC proporciona un manejador global de excepciones (un único componente por sistema) para centralizar el tratamiento de errores.

Clase de Excepción Personalizada

Se define una excepción personalizada extendiendo Exception para errores anticipados.


package com.empresa.excepciones;

public class ExcepcionPersonalizada extends Exception {
    private String mensaje;

    public ExcepcionPersonalizada(String msg) {
        super(msg);
        this.mensaje = msg;
    }

    public String obtenerMensaje() {
        return mensaje;
    }

    public void establecerMensaje(String msg) {
        this.mensaje = msg;
    }
}

Implementación del Manejador Global

El flujo consiste en que las excepciones se propagan manualmente desde DAO a servicio, luego a controlador, y finalmente al controlador frontal, que invoca el manejador global.

Lógica del manejador:

  • Analizar el tipo de excepción.
  • Si es una excepción personalizada, extraer su mensaje y mostrarlo en una página de error.
  • Si no, crear una excepción personalizada con el mensaje "Error desconocido".

package com.empresa.excepciones;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

public class ResolvedorExcepcionesGlobales implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolverExcepcion(HttpServletRequest solicitud,
            HttpServletResponse respuesta, Object manejador, Exception ex) {
        
        ExcepcionPersonalizada exPersonalizada;
        if (ex instanceof ExcepcionPersonalizada) {
            exPersonalizada = (ExcepcionPersonalizada) ex;
        } else {
            exPersonalizada = new ExcepcionPersonalizada("Error desconocido");
        }
        
        ModelAndView vista = new ModelAndView();
        vista.addObject("mensaje", exPersonalizada.obtenerMensaje());
        vista.establecerVista("paginaError");
        return vista;
    }
}

Página de Error

Una vista JSP simple para mostrar el mensaje de error.


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>Notificación de Error</title>
</head>
<body>
    ${mensaje}
</body>
</html>

Configuración en Spring

Registrar el manejador global en el archivo de configuración de Spring MVC.


<!-- Bean para el manejador global de excepciones -->
<bean class="com.empresa.excepciones.ResolvedorExcepcionesGlobales" />

Código de Prueba

Para probar, se pueden lanzar excepciones manualmente en controladores o servicios. Las excepciones personalizadas mostrarán mensajes específicos; otras excepciones mostrarán "Error desconocido".

Ejemplo en un controldaor:


@RequestMapping(value="/modificarProducto", method={RequestMethod.POST, RequestMethod.GET})
public String modificarProducto(Model modelo, @RequestParam(value="id", required=true) Integer productoId) throws Exception {
    ProductoPersonalizado producto = servicioProducto.buscarPorId(productoId);
    if (producto == null) {
        throw new ExcepcionPersonalizada("El producto no existe");
    }
    modelo.addAttribute("producto", producto);
    return "producto/editar";
}

Ejemplo en un servicio:


@Override
public ProductoPersonalizado buscarPorId(Integer id) throws Exception {
    Producto producto = mapeadorProducto.seleccionarPorClave(id);
    if (producto == null) {
        throw new ExcepcionPersonalizada("Producto no encontrado");
    }
    ProductoPersonalizado productoPersonalizado = new ProductoPersonalizado();
    BeanUtils.copiarPropiedades(producto, productoPersonalizado);
    return productoPersonalizado;
}

La ejecución se detiene al lanzar la excepción, evitando instrucciones posteriores. Excepciones relacionadas con lógica de negocio deben lanzarse en la capa de servicio, mientras que otras pueden manejarse en el controlador.

Etiquetas: Spring MVC java manejo de excepciones jsp Excepciones Personalizadas

Publicado el 7-4 17:46