Spring MVC Exception Handling es muy importante para asegurarse de que no estás enviando excepciones del servidor al cliente. Hoy veremos el manejo de excepciones en Spring utilizando @ExceptionHandler, @ControllerAdvice y HandlerExceptionResolver. Cualquier aplicación web requiere un buen diseño para el manejo de excepciones porque no queremos servir una página generada por el contenedor cuando nuestra aplicación lance una excepción no manejada.
Manejo de Excepciones en Spring
Tener un enfoque bien definido para el manejo de excepciones es una gran ventaja para cualquier marco de aplicación web, dicho esto, el marco Spring MVC cumple bien cuando se trata de manejar excepciones y errores en nuestras aplicaciones web. El marco Spring MVC proporciona las siguientes formas para ayudarnos a lograr un manejo robusto de excepciones.
- Basado en Controlador – Podemos definir métodos manejadores de excepciones en nuestras clases de controlador. Todo lo que necesitamos es anotar estos métodos con la anotación
@ExceptionHandler
. Esta anotación toma como argumento la clase Exception. Entonces, si hemos definido uno de estos para la clase Exception, entonces todas las excepciones lanzadas por nuestro método manejador de solicitudes serán tratadas. Estos métodos manejadores de excepciones son similares a otros métodos manejadores de solicitudes y podemos construir respuestas de error y responder con diferentes páginas de error. También podemos enviar una respuesta de error JSON, que veremos más adelante en nuestro ejemplo. Si hay múltiples métodos manejadores de excepciones definidos, entonces se utiliza el método manejador más cercano a la clase Exception. Por ejemplo, si tenemos dos métodos manejadores definidos para IOException y Exception y nuestro método manejador de solicitudes arroja IOException, entonces se ejecutará el método manejador para IOException. - Manejador Global de Excepciones – El manejo de excepciones es una preocupación transversal, debe realizarse para todos los puntos de corte en nuestra aplicación. Ya hemos analizado Spring AOP y por eso Spring proporciona la anotación
@ControllerAdvice
que podemos usar con cualquier clase para definir nuestro manejador global de excepciones. Los métodos manejadores en el Asesor Global del Controlador son iguales que los métodos manejadores de excepciones basados en controladores y se utilizan cuando la clase del controlador no puede manejar la excepción. - HandlerExceptionResolver – Para excepciones genéricas, la mayoría de las veces servimos páginas estáticas. El Framework Spring proporciona la interfaz
HandlerExceptionResolver
que podemos implementar para crear un manejador global de excepciones. La razón detrás de esta forma adicional de definir un manejador global de excepciones es que el framework Spring también proporciona clases de implementación predeterminadas que podemos definir en nuestro archivo de configuración de beans de Spring para obtener beneficios en el manejo de excepciones del framework Spring.SimpleMappingExceptionResolver
es la clase de implementación predeterminada, nos permite configurar excepcionesMappings donde podemos especificar qué recurso utilizar para una excepción particular. También podemos anularlo para crear nuestro propio manejador global con nuestros cambios específicos de la aplicación, como el registro de mensajes de excepción.
Creemos un proyecto Spring MVC donde analizaremos la implementación de enfoques de manejo de excepciones y errores basados en Controlador, basados en AOP y basados en Resolver de Excepciones. También escribiremos un método de manejador de excepciones que devolverá una respuesta JSON. Si eres nuevo en JSON en Spring, lee Tutorial JSON Restful de Spring. Nuestro proyecto final se verá como la imagen a continuación, examinaremos todos los componentes de nuestra aplicación uno por uno.
Manejo de Excepciones de Primavera Dependencias de Maven
Además de las dependencias estándar de Spring MVC, también necesitaríamos la dependencia Jackson JSON para el soporte JSON. Nuestro archivo pom.xml final se ve así.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.spring</groupId>
<artifactId>SpringExceptionHandling</artifactId>
<name>SpringExceptionHandling</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.6</java-version>
<org.springframework-version>4.0.2.RELEASE</org.springframework-version>
<org.aspectj-version>1.7.4</org.aspectj-version>
<org.slf4j-version>1.7.5</org.slf4j-version>
<jackson.databind-version>2.2.3</jackson.databind-version>
</properties>
<dependencies>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind-version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
I have updated Spring Framework, AspectJ, Jackson and slf4j versions to use the latest one.
Descriptor de Implementación de Manejo de Excepciones de Spring MVC
Nuestro archivo web.xml se ve así.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/resources/404.jsp</location>
</error-page>
</web-app>
La mayor parte es para enchufar Spring Framework en nuestra aplicación web, excepto la página de error definida para el error 404. Entonces, cuando nuestra aplicación arroje un error 404, esta página se utilizará como respuesta. Esta configuración es utilizada por el contenedor cuando nuestra aplicación web de Spring arroja el código de error 404.
Manejo de Excepciones de Primavera – Clases de Modelo
I have defined Employee bean as model class, however we will be using it in our application just to return valid response in specific scenario. We will be deliberately throwing different types of exceptions in most of the cases.
package com.journaldev.spring.model;
public class Employee {
private String name;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Dado que también estaremos devolviendo una respuesta JSON, creemos un bean de Java con detalles de excepción que se enviarán como respuesta.
package com.journaldev.spring.model;
public class ExceptionJSONInfo {
private String url;
private String message;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Manejo de Excepciones de Spring – Clase de Excepción Personalizada
Creemos una clase de excepción personalizada para ser utilizada por nuestra aplicación.
package com.journaldev.spring.exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Employee Not Found") //404
public class EmployeeNotFoundException extends Exception {
private static final long serialVersionUID = -3332292346834265371L;
public EmployeeNotFoundException(int id){
super("EmployeeNotFoundException with id="+id);
}
}
Observe que podemos usar la anotación @ResponseStatus
con clases de excepción para definir el código HTTP que será enviado por nuestra aplicación cuando este tipo de excepción sea lanzado por nuestra aplicación y manejado por nuestras implementaciones de manejo de excepciones. Como puede ver, estoy estableciendo el estado HTTP como 404 y tenemos una página de error definida para esto, así que nuestra aplicación debería usar la página de error para este tipo de excepción si no estamos devolviendo ninguna vista. También podemos anular el código de estado en nuestro método de controlador de manejo de excepciones, piense en ello como el código de estado HTTP predeterminado cuando nuestro método de manejo de excepciones no está devolviendo ninguna página de vista como respuesta.
Manejo de Excepciones del Controlador de Spring MVC
Vamos a ver nuestra clase de controlador donde lanzaremos diferentes tipos de excepciones.
package com.journaldev.spring.controllers;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.journaldev.spring.exceptions.EmployeeNotFoundException;
import com.journaldev.spring.model.Employee;
import com.journaldev.spring.model.ExceptionJSONInfo;
@Controller
public class EmployeeController {
private static final Logger logger = LoggerFactory.getLogger(EmployeeController.class);
@RequestMapping(value="/emp/{id}", method=RequestMethod.GET)
public String getEmployee(@PathVariable("id") int id, Model model) throws Exception{
// lanzando deliberadamente diferentes tipos de excepciones
if(id==1){
throw new EmployeeNotFoundException(id);
}else if(id==2){
throw new SQLException("SQLException, id="+id);
}else if(id==3){
throw new IOException("IOException, id="+id);
}else if(id==10){
Employee emp = new Employee();
emp.setName("Pankaj");
emp.setId(id);
model.addAttribute("employee", emp);
return "home";
}else {
throw new Exception("Generic Exception, id="+id);
}
}
@ExceptionHandler(EmployeeNotFoundException.class)
public ModelAndView handleEmployeeNotFoundException(HttpServletRequest request, Exception ex){
logger.error("Requested URL="+request.getRequestURL());
logger.error("Exception Raised="+ex);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("exception", ex);
modelAndView.addObject("url", request.getRequestURL());
modelAndView.setViewName("error");
return modelAndView;
}
}
Tenga en cuenta que para el controlador EmployeeNotFoundException, estoy devolviendo ModelAndView y, por lo tanto, el código de estado HTTP se enviará como OK (200). Si estuviera devolviendo void, entonces el código de estado HTTP se enviaría como 404. Investigaremos este tipo de implementación en nuestra implementación de controlador de excepciones global. Dado que solo estoy manejando EmployeeNotFoundException en el controlador, todas las demás excepciones lanzadas por nuestro controlador serán manejadas por el controlador de excepciones global.
@ControllerAdvice y @ExceptionHandler
Aquí está nuestra clase de controlador de excepciones global. Tenga en cuenta que la clase está anotada con la anotación @ControllerAdvice . Además, los métodos están anotados con la anotación @ExceptionHandler .
package com.journaldev.spring.controllers;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(SQLException.class)
public String handleSQLException(HttpServletRequest request, Exception ex){
logger.info("SQLException Occured:: URL="+request.getRequestURL());
return "database_error";
}
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="IOException occured")
@ExceptionHandler(IOException.class)
public void handleIOException(){
logger.error("IOException handler executed");
// devolviendo código de error 404
}
}
Ten en cuenta que para SQLException, estoy devolviendo database_error.jsp como página de respuesta con un código de estado http 200. Para IOException, estamos devolviendo vacío con un código de estado 404, por lo que en este caso se utilizará nuestra página de error. Como puedes ver, no estoy manejando ningún otro tipo de excepción aquí, esa parte la he dejado para la implementación de HandlerExceptionResolver.
HandlerExceptionResolver
Solo estamos extendiendo SimpleMappingExceptionResolver y anulando uno de sus métodos, pero podemos anular su método más importante resolveException
para registrar y enviar diferentes tipos de páginas de vista. Pero eso es lo mismo que usar la implementación de ControllerAdvice, así que lo estoy dejando. Lo usaremos para configurar la página de vista para todas las demás excepciones no manejadas por nosotros, respondiendo con una página de error genérica.
Archivo de Configuración de Manejo de Excepciones de Spring
Nuestro archivo de configuración de beans de Spring se ve así. Código de spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean id="simpleMappingExceptionResolver" class="com.journaldev.spring.resolver.MySimpleMappingExceptionResolver">
<beans:property name="exceptionMappings">
<beans:map>
<beans:entry key="Exception" value="generic_error"></beans:entry>
</beans:map>
</beans:property>
<beans:property name="defaultErrorView" value="generic_error"/>
</beans:bean>
<!-- Configure to plugin JSON as request and response in method handler -->
<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:ref bean="jsonMessageConverter"/>
</beans:list>
</beans:property>
</beans:bean>
<!-- Configure bean to convert JSON to POJO and vice versa -->
<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</beans:bean>
<context:component-scan base-package="com.journaldev.spring" />
</beans:beans>
Observa los beans configurados para admitir JSON en nuestra aplicación web. La única parte relacionada con el manejo de excepciones es la definición del bean simpleMappingExceptionResolver, donde estamos definiendo generic_error.jsp como la página de vista para la clase Exception. Esto asegura que cualquier excepción no manejada por nuestra aplicación no resultará en el envío de una página de error generada por el servidor como respuesta.
Spring MVC Manejo de Excepciones Páginas de Vista JSP
Es hora de analizar la última parte de nuestra aplicación, nuestras páginas de vista que se utilizarán en nuestra aplicación. Código de home.jsp:
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h3>Hello ${employee.name}!</h3><br>
<h4>Your ID is ${employee.id}</h4>
</body>
</html>
home.jsp se utiliza para responder con datos válidos, es decir, cuando obtenemos el id como 10 en la solicitud del cliente. Código de 404.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>404 Error Page</title>
</head>
<body>
<h2>Resource Not Found Error Occured, please contact support.</h2>
</body>
</html>
404.jsp se utiliza para generar la vista para el código de estado http 404, para nuestra implementación, esta debería ser la respuesta cuando obtenemos el id como 3 en la solicitud del cliente. Código de error.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Error Page</title>
</head>
<body>
<h2>Application Error, please contact support.</h2>
<h3>Debug Information:</h3>
Requested URL= ${url}<br><br>
Exception= ${exception.message}<br><br>
<strong>Exception Stack Trace</strong><br>
<c:forEach items="${exception.stackTrace}" var="ste">
${ste}
</c:forEach>
</body>
</html>
error.jsp se utiliza cuando el método del controlador de nuestra clase manejadora de solicitudes está lanzando EmployeeNotFoundException. Deberíamos obtener esta página como respuesta cuando el valor del id es 1 en la solicitud del cliente. Código de database_error.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Database Error Page</title>
</head>
<body>
<h2>Database Error, please contact support.</h2>
</body>
</html>
database_error.jsp se utiliza cuando nuestra aplicación está lanzando SQLException, como se configura en la clase GlobalExceptionHandler. Deberíamos obtener esta página como respuesta cuando el valor del id es 2 en la solicitud del cliente. Código de generic_error.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Generic Error Page</title>
</head>
<body>
<h2>Unknown Error Occured, please contact support.</h2>
</body>
</html>
Esta debería ser la página como respuesta cuando ocurre cualquier excepción no manejada por el código de nuestra aplicación y el bean simpleMappingExceptionResolver se encarga de eso. Deberíamos obtener esta página como respuesta cuando el valor de id en la solicitud del cliente sea cualquier cosa que no sea 1, 2, 3 o 10.
Ejecutando la aplicación de manejo de excepciones de Spring MVC
Simplemente despliega la aplicación en el contenedor de servlets que estás utilizando. Para este ejemplo, estoy usando Apache Tomcat 7. A continuación, se muestran imágenes de las diferentes páginas de respuesta devueltas por nuestra aplicación según el valor de id. ID=10, respuesta válida. ID=1, se utiliza un controlador para manejar la excepción
ID=2, se utiliza un manejador de excepciones global con la vista como respuesta
ID=3, se utiliza una página de error 404
ID=4, se utiliza simpleMappingExceptionResolver para la vista de respuesta
Como puedes ver, obtuvimos la respuesta esperada en todos los casos.
Manejador de Excepciones de Spring: Respuesta en JSON
Estamos casi terminando con nuestro tutorial, excepto la última parte donde explicaré cómo enviar una respuesta en JSON desde los métodos del manejador de excepciones. Nuestra aplicación tiene todas las dependencias de JSON configuradas, y jsonMessageConverter está configurado. Todo lo que necesitamos hacer es implementar el método del manejador de excepciones. Para mayor simplicidad, reescribiré el método handleEmployeeNotFoundException() del controlador de empleados para devolver una respuesta en JSON. Simplemente actualice el método del manejador de excepciones del controlador de empleados con el código a continuación y despliegue la aplicación nuevamente.
@ExceptionHandler(EmployeeNotFoundException.class)
public @ResponseBody ExceptionJSONInfo handleEmployeeNotFoundException(HttpServletRequest request, Exception ex){
ExceptionJSONInfo response = new ExceptionJSONInfo();
response.setUrl(request.getRequestURL().toString());
response.setMessage(ex.getMessage());
return response;
}
Ahora, cuando usemos el id como 1 en la solicitud del cliente, obtendremos la siguiente respuesta en JSON, como se muestra en la imagen a continuación. Eso es todo para el manejo de excepciones de Spring y el manejo de excepciones de Spring MVC. Por favor, descargue la aplicación desde la siguiente URL y juegue con ella para aprender más.