Spring MVC Exception Handling – Wie funktioniert das?

Spring MVC Exception Handling ist sehr wichtig, um sicherzustellen, dass keine Server-Ausnahmen an den Client gesendet werden. Heute werden wir uns das Spring Exception Handling ansehen, das @ExceptionHandler, @ControllerAdvice und HandlerExceptionResolver verwendet. Jede Webanwendung benötigt ein gutes Design für die Ausnahmebehandlung, weil wir keine vom Container generierte Seite ausliefern wollen, wenn eine nicht behandelte Ausnahme von unserer Anwendung geworfen wird.

Spring Exception Handling

Ein gut definierter Ansatz für das Exception Handling ist ein großer Pluspunkt für jedes Webanwendungs-Framework. Diesbezüglich liefert das Spring MVC Framework gute Ergebnisse, wenn es um das Handling von Ausnahmen und Fehlern in unseren Webanwendungen geht. Das Spring MVC Framework bietet folgende Wege, um uns bei der Erreichung einer robusten Ausnahmebehandlung zu unterstützen.

  1. Controller Based Exception Handling – Wir können Ausnahmebehandler-Methoden in unseren Controller-Klassen definieren. Alles, was wir tun müssen, ist, diese Methoden mit der @ExceptionHandler-Annotation zu annotieren. Diese Annotation nimmt die Exception-Klasse als Argument. Wenn wir also eine solche für die Exception-Klasse definiert haben, dann werden alle Ausnahmen, die von unserer Request-Handler-Methode geworfen werden, behandelt. Diese Ausnahmebehandler-Methoden sind wie andere Request-Handler-Methoden und wir können eine Fehlerantwort erstellen und mit einer unterschiedlichen Fehlerseite reagieren. Wir können auch eine JSON-Fehlerantwort senden, die wir später in unserem Beispiel betrachten werden. Wenn mehrere Ausnahmebehandler-Methoden definiert sind, wird die Methode verwendet, die der Exception-Klasse am nächsten ist. Zum Beispiel, wenn wir zwei Handler-Methoden für IOException und Exception definiert haben und unsere Request-Handler-Methode eine IOException wirft, dann wird die Handler-Methode für IOException ausgeführt.
  2. Global Exception Handling – Exception Handling ist ein übergreifendes Anliegen, das für alle Pointcuts in unserer Anwendung durchgeführt werden sollte. Wir haben bereits Spring AOP betrachtet, und deshalb bietet Spring die @ControllerAdvice-Annotation, die wir mit jeder Klasse verwenden können, um unseren globalen Ausnahmebehandler zu definieren. Die Handler-Methoden in Global Controller Advice sind die gleichen wie die Controller-basierten Ausnahmebehandler-Methoden und werden verwendet, wenn die Controller-Klasse die Ausnahme nicht behandeln kann.
  3. HandlerExceptionResolver – Für generische Ausnahmen liefern wir meist statische Seiten aus. Das Spring Framework bietet die HandlerExceptionResolver-Schnittstelle, die wir implementieren können, um einen globalen Ausnahmebehandler zu erstellen. Der Grund für diese zusätzliche Möglichkeit, einen globalen Ausnahmebehandler zu definieren, liegt darin, dass das Spring Framework auch Standard-Implementierungsklassen bietet, die wir in unserer Spring-Bean-Konfigurationsdatei definieren können, um die Vorteile der Spring Framework-Ausnahmebehandlung zu nutzen. SimpleMappingExceptionResolver ist die Standard-Implementierungsklasse, die es uns ermöglicht, exceptionMappings zu konfigurieren, bei denen wir angeben können, welche Ressource für eine bestimmte Ausnahme verwendet werden soll. Wir können sie auch überschreiben, um unseren eigenen globalen Handler mit anwendungsspezifischen Änderungen zu erstellen, wie zum Beispiel das Protokollieren von Ausnahmemeldungen.

Lassen Sie uns ein Spring MVC-Projekt erstellen, in dem wir die Implementierung von Controller-basierten, AOP-basierten und Exception Resolver-basierten Ansätzen für Exception Handling und Fehlerbehandlung betrachten werden. Wir werden auch eine Ausnahmebehandler-Methode schreiben, die eine JSON-Antwort zurückgibt. Wenn Sie neu bei JSON in Spring sind, lesen Sie das Spring Restful JSON Tutorial. Unser fertiges Projekt wird wie das untenstehende Bild aussehen, wir werden uns alle Komponenten unserer Anwendung nacheinander ansehen.

Spring Exception Handling Maven-Abhängigkeiten

Abgesehen von den Standard-Spring MVC-Abhängigkeiten benötigen wir auch die Jackson JSON-Abhängigkeit für JSON-Unterstützung. Unsere endgültige pom.xml-Datei sieht wie folgt aus.

<?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>

Ich habe die Versionen von Spring Framework, AspectJ, Jackson und slf4j aktualisiert, um die neuesten zu verwenden.

Spring MVC Exception Handling Deployment Descriptor

Unsere web.xml-Datei sieht wie folgt aus.

<?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>

Der größte Teil dient dazu, das Spring Framework in unsere Webanwendung zu integrieren, mit Ausnahme der für den 404-Fehler definierten Fehlerseite. Wenn also unsere Anwendung einen 404-Fehler auslöst, wird diese Seite als Antwort verwendet. Diese Konfiguration wird vom Container verwendet, wenn unsere Spring-Webanwendung den 404-Fehlercode auslöst.

Spring Exception Handling – Modelklassen

Ich habe die Employee-Bean als Modelklasse definiert, jedoch werden wir sie in unserer Anwendung nur verwenden, um eine gültige Antwort in einem bestimmten Szenario zurückzugeben. Wir werden absichtlich verschiedene Arten von Ausnahmen in den meisten Fällen auslösen.

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;
	}
}

Da wir auch eine JSON-Antwort zurückgeben werden, erstellen wir eine Java-Bean mit Ausnahmedetails, die als Antwort gesendet werden.

Da wir auch eine JSON-Antwort zurückgeben werden, erstellen wir eine Java-Bean mit Ausnahmedetails, die als Antwort gesendet werden.

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;
	}
}

Spring Exception Handling – Benutzerdefinierte Ausnahmeklasse

Lassen Sie uns eine benutzerdefinierte Ausnahmeklasse erstellen, die von unserer Anwendung verwendet wird.

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);
	}
}

Beachten Sie, dass wir die @ResponseStatus-Annotation mit Ausnahmeklassen verwenden können, um den HTTP-Code zu definieren, der von unserer Anwendung gesendet wird, wenn dieser Typ von Ausnahme von unserer Anwendung ausgelöst und von unseren Ausnahmebehandlungsimplementierungen gehandhabt wird.

Spring MVC Exception Handling Controller-Klasse Ausnahmebehandler

Lassen Sie uns unsere Controller-Klasse betrachten, in der wir verschiedene Arten von Ausnahmen auslösen werden.

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{
        //deliberately throwing different types of exception
        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;
    }   
}

Beachten Sie, dass ich für den EmployeeNotFoundException-Handler ModelAndView zurückgebe und daher der HTTP-Statuscode als OK (200) gesendet wird.

@ControllerAdvice und @ExceptionHandler

Hier ist unsere globale Exception-Handler-Controller-Klasse. Beachten Sie, dass die Klasse mit der @ControllerAdvice-Annotation annotiert ist. Auch die Methoden sind mit der @ExceptionHandler-Annotation annotiert.

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");
        //returning 404 error code
    }
}

Beachten Sie, dass ich für SQLException database_error.jsp als Antwortseite mit dem HTTP-Statuscode 200 zurückgebe. Für IOException geben wir void mit dem Statuscode 404 zurück, sodass in diesem Fall unsere Fehlerseite verwendet wird.

HandlerExceptionResolver

Wir erweitern lediglich SimpleMappingExceptionResolver und überschreiben eine der Methoden, aber wir könnten dessen wichtigste Methode resolveException zum Protokollieren und Senden verschiedener Arten von Ansichtsseiten überschreiben. Das ist jedoch dasselbe wie die Verwendung der ControllerAdvice-Implementierung, daher lasse ich es. Wir werden es verwenden, um die Ansichtsseite für alle anderen von uns nicht behandelten Ausnahmen zu konfigurieren, indem wir mit einer generischen Fehlerseite antworten.

Spring Exception Handling Konfigurationsdatei

Unsere Spring-Bean-Konfigurationsdatei sieht wie folgt aus. spring.xml-Code:

<?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>

Beachten Sie die für die Unterstützung von JSON in unserer Webanwendung konfigurierten Beans. Der einzige Teil, der mit der Ausnahmebehandlung zusammenhängt, ist die Definition des Beans simpleMappingExceptionResolver, wo wir generic_error.jsp als Ansichtsseite für die Exception-Klasse definieren. Dies stellt sicher, dass jede von unserer Anwendung nicht behandelte Ausnahme nicht dazu führt, dass eine vom Server generierte Fehlerseite als Antwort gesendet wird.

Spring MVC Exception Handling JSP-Ansichtsseiten

<%@ 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 wird verwendet, um mit gültigen Daten zu antworten, d.h. wenn wir in der Client-Anfrage die ID 10 erhalten.

404.jsp Code

<%@ 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 wird verwendet, um eine Ansicht für den 404 HTTP-Statuscode zu generieren. In unserer Implementierung sollte dies die Antwort sein, wenn wir in der Client-Anfrage die ID 3 erhalten.

error.jsp Code

<%@ 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 wird verwendet, um eine Fehleransicht zu generieren, typischerweise wenn eine nicht behandelte Ausnahme in der Anwendung auftritt.

Spring MVC Exception Handling JSP-Ansichtsseiten

Datenbankfehlerseite – 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 wird verwendet, wenn unsere Anwendung eine SQLException auslöst, wie in der GlobalExceptionHandler-Klasse konfiguriert. Wir sollten diese Seite als Antwort erhalten, wenn der ID-Wert in der Client-Anfrage 2 ist.

Generische Fehlerseite – 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>

Diese Seite wird verwendet, wenn eine Ausnahme auftritt, die nicht von unserem Anwendungscode behandelt wird, und der Bean simpleMappingExceptionResolver kümmert sich darum. Wir sollten diese Seite als Antwort erhalten, wenn der ID-Wert in der Client-Anfrage etwas anderes als 1, 2, 3 oder 10 ist.

Ausführen der Spring MVC Exception Handling Anwendung

Stellen Sie einfach die Anwendung im von Ihnen verwendeten Servlet-Container bereit. Ich verwende Apache Tomcat 7 für dieses Beispiel. Die untenstehenden Bilder zeigen die verschiedenen Antwortseiten, die von unserer Anwendung basierend auf dem ID-Wert zurückgegeben werden. ID=10, gültige Antwort.

ID=1, controllerbasierte Ausnahmebehandler verwendet

ID=2, globaler Ausnahmebehandler verwendet mit Ansicht als Antwort

ID=3, 404-Fehlerseite verwendet

ID=4, simpleMappingExceptionResolver verwendet für Antwortansicht

Wie Sie sehen können, haben wir in allen Fällen die erwartete Antwort erhalten.

Spring Exception Handler JSON-Antwort

Wir sind fast fertig mit unserem Tutorial, bis auf den letzten Teil, in dem ich erkläre, wie man eine JSON-Antwort von den Ausnahmebehandlermethoden sendet. Unsere Anwendung hat alle JSON-Abhängigkeiten und jsonMessageConverter ist konfiguriert, alles, was wir tun müssen, ist die Ausnahmebehandlermethode zu implementieren. Zur Vereinfachung werde ich die Methode handleEmployeeNotFoundException() des EmployeeController umschreiben, um eine JSON-Antwort zurückzugeben. Aktualisieren Sie einfach die Ausnahmebehandlermethode des EmployeeController mit dem untenstehenden Code und stellen Sie die Anwendung erneut bereit.

@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;
}

Wenn wir nun in der Client-Anfrage die ID 1 verwenden, erhalten wir die folgende JSON-Antwort, wie im untenstehenden Bild gezeigt.

Das ist alles zum Thema Spring Exception Handling und Spring MVC Exception Handling und wie das Konzept funktioniert.

Kostenlosen Account erstellen

Registrieren Sie sich jetzt und erhalten Sie Zugang zu unseren Cloud Produkten.

Das könnte Sie auch interessieren: