Trajtimi i përjashtimeve të pranverës MVC - @ControllerAdvice, @ExceptionHandler, HandlerExceptionResolver


Trajtimi i përjashtimeve të Spring MVC është shumë i rëndësishëm për t'u siguruar që nuk po dërgoni përjashtime nga serveri te klienti. Sot do të shqyrtojmë trajtimin e përjashtimeve të pranverës duke përdorur aplikacionin në internet që kërkon dizajn të mirë për trajtimin e përjashtimeve sepse ne nuk duam të shërbejmë faqen e krijuar nga kontejnerët kur ndonjë përjashtim i patrajtuar hidhet nga aplikacioni ynë.

Trajtimi i përjashtimeve të pranverës

Të kesh një qasje të mirëpërcaktuar të trajtimit të përjashtimeve është një pikë e madhe plus për çdo kornizë aplikacioni në internet, duke thënë se kuadri Spring MVC ofron mirë kur bëhet fjalë për trajtimin e përjashtimeve dhe gabimeve në aplikacionet tona në ueb. Spring MVC Framework ofron mënyrat e mëposhtme për të na ndihmuar të arrijmë trajtimin e fuqishëm të përjashtimeve.

  1. Bazuar në kontrollues - Ne mund të përcaktojmë metodat e trajtuesit të përjashtimeve në klasat tona të kontrollorëve. Gjithçka që na duhet është të shënojmë këto metoda me shënimin @ExceptionHandler. Ky shënim merr klasën e përjashtimit si argument. Pra, nëse kemi përcaktuar një nga këto për klasën Exception, atëherë të gjitha përjashtimet e hedhura nga metoda jonë e mbajtësit të kërkesave do të kenë trajtuar. Këto metoda të trajtuesit të përjashtimeve janë njësoj si metodat e tjera të trajtuesit të kërkesave dhe ne mund të ndërtojmë përgjigje gabimi dhe të përgjigjemi me faqe të ndryshme gabimi. Ne gjithashtu mund të dërgojmë përgjigje gabimi JSON, të cilën do ta shohim më vonë në shembullin tonë. Nëse përcaktohen metoda të shumta të mbajtësit të përjashtimeve, atëherë përdoret metoda mbajtëse që është më afër klasës Exception. Për shembull, nëse kemi dy metoda mbajtëse të përcaktuara për IOException dhe Exception dhe metoda jonë e trajtuesit të kërkesave hedh IOException, atëherë metoda e mbajtësit për IOException do të ekzekutohet.
  2. Global Exception Handler - Trajtimi i përjashtimeve është një shqetësim ndërsektorial, ai duhet të bëhet për të gjitha pikat në aplikacionin tonë. Ne kemi parë tashmë në Spring AOP dhe kjo është arsyeja pse Spring ofron shënimin @ControllerAdvice që mund ta përdorim me çdo klasë për të përcaktuar mbajtësin tonë global të përjashtimeve. Metodat e mbajtësit në Këshillat Globale të Kontrolluesit janë të njëjta me metodat e trajtuesit të përjashtimeve të bazuara në kontrollues dhe përdoren kur klasa e kontrolluesit nuk është në gjendje të trajtojë përjashtimin.
  3. HandlerExceptionResolver - Për përjashtime të përgjithshme, në shumicën e rasteve ne shërbejmë faqe statike. Spring Framework ofron ndërfaqen HandlerExceptionResolver që mund ta implementojmë për të krijuar mbajtës global të përjashtimeve. Arsyeja pas kësaj mënyre shtesë për të përcaktuar mbajtësin global të përjashtimeve është se kuadri Spring ofron gjithashtu klasa të parazgjedhura të zbatimit që ne mund t'i përcaktojmë në skedarin tonë të konfigurimit të fasules së pranverës për të marrë përfitimet e trajtimit të përjashtimeve të kornizës së pranverës. SimpleMappingExceptionResolver është klasa e parazgjedhur e zbatimit, ajo na lejon të konfigurojmë extremeMappings ku mund të specifikojmë se cilin burim të përdorim për një përjashtim të caktuar. Ne gjithashtu mund ta anashkalojmë atë për të krijuar mbajtësin tonë global me ndryshime specifike të aplikacionit tonë, të tilla si regjistrimi i mesazheve të përjashtimit.

Pranvera Trajtimi i Varësive të Maven

Përveç varësive standarde Spring MVC, do të na duhej edhe varësia Jackson JSON për mbështetjen JSON. Skedari ynë i fundit pom.xml duket si më poshtë.

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

Kam përditësuar versionet Spring Framework, AspectJ, Jackson dhe slf4j për të përdorur versionin më të fundit.

Përshkruesi i vendosjes së trajtimit të përjashtimit të pranverës MVC

Skedari ynë web.xml duket si më poshtë.

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

Pjesa më e madhe është për kyçjen e Spring Framework për aplikacionin tonë në internet, përveç faqes së gabimit të përcaktuar për gabimin 404. Pra, kur aplikacioni ynë do të hedhë gabimin 404, kjo faqe do të përdoret si përgjigje. Ky konfigurim përdoret nga kontejneri kur aplikacioni ynë i uebit i pranverës hedh kodin e gabimit 404.

Trajtimi i përjashtimeve të pranverës - klasa model

Unë e kam përcaktuar Employee Bean si klasë modeli, megjithatë ne do ta përdorim atë në aplikacionin tonë vetëm për të kthyer përgjigje të vlefshme në një skenar specifik. Ne do të hedhim qëllimisht lloje të ndryshme përjashtimesh në shumicën e rasteve.

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

Meqenëse do të kthejmë edhe përgjigjen JSON, le të krijojmë një java bean me detaje përjashtimi që do të dërgohen si përgjigje.

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

Trajtimi i përjashtimeve të pranverës - Klasa e përjashtimeve me porosi

Le të krijojmë një klasë përjashtimi të personalizuar që do të përdoret nga aplikacioni ynë.

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

Vini re se ne mund të përdorim shënimin @ResponseStatus me klasa përjashtimi për të përcaktuar kodin HTTP që do të dërgohet nga aplikacioni ynë kur ky lloj përjashtimi hidhet nga aplikacioni ynë dhe trajtohet nga zbatimet tona të trajtimit të përjashtimeve. Siç mund ta shihni që unë po vendos statusin HTTP si 404 dhe ne kemi një faqe gabimi të përcaktuar për këtë, kështu që aplikacioni ynë duhet të përdorë faqen e gabimit për këtë lloj përjashtimi nëse nuk po kthejmë asnjë pamje. Ne gjithashtu mund të anashkalojmë kodin e statusit në metodën tonë të mbajtësit të përjashtimeve, ta mendojmë si kodin e statusit të paracaktuar http kur metoda jonë e trajtuesit të përjashtimeve nuk po kthen asnjë faqe pamjeje si përgjigje.

Pranvera MVC Trajtimi i Kontrollit të Përjashtimeve të Klasës

Le të shohim klasën tonë të kontrolluesit ku do të hedhim lloje të ndryshme përjashtimesh.

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

Vini re se për mbajtësin EmployeeNotFoundException, unë po kthej ModelAndView dhe kështu kodi i statusit http do të dërgohet si OK (200). Nëse do të ishte kthyer i pavlefshëm, atëherë kodi i statusit http do të ishte dërguar si 404. Ne do të shqyrtojmë këtë lloj zbatimi në zbatimin tonë të trajtuesit global të përjashtimeve. Meqenëse unë po trajtoj vetëm EmployeeNotFoundException në kontrollues, të gjitha përjashtimet e tjera të hedhura nga kontrolluesi ynë do të trajtohen nga mbajtësi global i përjashtimeve.

@ControllerAdvice dhe @ExceptionHandler

Këtu është klasa jonë globale e kontrolluesit të mbajtësve të përjashtimeve. Vini re se klasa është e shënuar me shënimin @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");
		//returning 404 error code
	}
}

Vini re se për SQLException, unë po kthej database_error.jsp si faqe përgjigjeje me kodin e statusit http si 200. Për IOException, ne po kthejmë void me kodin e statusit si 404, kështu që faqja jonë e gabimit do të përdoret në këtë rast. Siç mund ta shihni që unë nuk po trajtoj asnjë lloj tjetër përjashtimi këtu, atë pjesë e kam lënë për zbatimin e HandlerExceptionResolver.

HandlerExceptionResolver

Ne thjesht po zgjerojmë SimpleMappingExceptionResolver dhe po anashkalojmë një nga metodat, por mund të anashkalojmë metodën më të rëndësishme resolveException për regjistrimin dhe dërgimin e llojeve të ndryshme të faqeve të shikimit. Por kjo është njësoj si përdorimi i zbatimit të ControllerAdvice, kështu që po e lë. Ne do ta përdorim atë për të konfiguruar faqen e shikimit për të gjitha përjashtimet e tjera që nuk trajtohen nga ne, duke iu përgjigjur me faqen e gabimit të përgjithshëm.

Skedari i konfigurimit të trajtimit të përjashtimit të pranverës

Skedari ynë i konfigurimit të fasules së pranverës duket si më poshtë. Kodi 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>

Vini re fasulet e konfiguruara për të mbështetur JSON në aplikacionin tonë në ueb. E vetmja pjesë që lidhet me trajtimin e përjashtimeve është përkufizimi i thjeshtë i beanMappingExceptionResolver ku ne po përcaktojmë generic_error.jsp si faqen e pamjes për klasën Exception. Kjo sigurohuni që çdo përjashtim që nuk trajtohet nga aplikacioni ynë nuk do të rezultojë në dërgimin e faqes së gabimit të gjeneruar nga serveri si përgjigje.

Pranvera MVC Përjashtimi Trajtimi i Faqeve Shiko JSP

Është koha për të parë pjesën e fundit të aplikacionit tonë, faqet tona të shikimit që do të përdoren në aplikacionin tonë. Kodi 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 përdoret për t'iu përgjigjur me të dhëna të vlefshme, d.m.th. kur marrim ID si 10 në kërkesën e klientit. Kodi 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 përdoret për gjenerimin e pamjes për kodin e statusit 404 http, për zbatimin tonë kjo duhet të jetë përgjigja kur marrim ID si 3 në kërkesën e klientit. kodi 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 përdoret kur metoda jonë e trajtuesit të kërkesave të klasës së kontrolluesit po hedh EmployeeNotFoundException. Ne duhet ta marrim këtë faqe si përgjigje kur vlera e ID-së është 1 në kërkesën e klientit. Kodi i 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 përdoret kur aplikacioni ynë po hedh SQLException, siç është konfiguruar në klasën GlobalExceptionHandler. Ne duhet ta marrim këtë faqe si përgjigje kur vlera e ID-së është 2 në kërkesën e klientit. Kodi 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>

Kjo duhet të jetë faqja si përgjigje kur ndodh ndonjë përjashtim që nuk trajtohet nga kodi ynë i aplikacionit dhe simpleMappingExceptionResolver bean kujdeset për këtë. Ne duhet ta marrim këtë faqe si përgjigje kur vlera e ID-së në kërkesën e klientit është diçka tjetër përveç 1,2,3 ose 10.

Ekzekutimi i aplikacionit Spring MVC Exception Handling

Përgjigja JSON e mbajtësit të përjashtimit të pranverës

Pothuajse kemi mbaruar me tutorialin tonë, përveç pjesës së fundit ku do të shpjegoj se si të dërgoj përgjigjen JSON nga metodat e trajtuesit të përjashtimeve. Aplikacioni ynë ka të gjitha varësitë JSON dhe jsonMessageConverter është i konfiguruar, gjithçka që na nevojitet për të zbatuar metodën e trajtuesit të përjashtimeve. Për thjeshtësi, unë do të rishkruaj metodën EmployeeController handleEmployeeNotFoundException() për të kthyer përgjigjen JSON. Thjesht përditësoni metodën e trajtuesit të përjashtimeve të EmployeeController me kodin e mëposhtëm dhe vendoseni përsëri aplikacionin.

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

Shkarkoni Projektin e Trajtimit të Përjashtimeve të Pranverës