在这篇文章中,我们将看到如何在 Spring MVC 中使用 @ControllerAdvice 进行异常处理。在上一篇文章中,我们已经看到了如何使用 @ExceptionHandler 来处理异常,但是@ExceptionHandler 只能应用于一个控制器,但是如果您想全局处理异常,即跨多个控制器怎么办。您可以使用 @ControllerAdvice 全局处理异常。 让我们借助示例来理解这一点:
1) 在 Eclipse 中使用 maven创建一个 名为“SpringMVCControllerAdviceExample”的动态 Web 项目
2) 我们的 pom.xml 如下所示
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.arpit.java2blog</groupId> <artifactId> SpringMVCControllerAdviceExample</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name> SpringMVCControllerAdviceExample Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.4.1</version> </dependency> </dependencies> <build> <finalName> SpringMVCControllerAdviceExample</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> </plugins> </build> <properties> <spring.version>4.2.1.RELEASE</spring.version> <jdk.version>1.7</jdk.version> </properties> </project>
3) 改变web.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>Archetype Created Web Application</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>springrest</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springrest</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
4) 在 /WEB-INF/ 文件夹中创建一个名为 springrest-servlet.xml 的 xml 文件。 如果您想使用不同的 spring 包来搜索控制器,请更改 context:component-scan。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <mvc:annotation-driven/> <context:component-scan base-package="org.arpit.java2blog.controller" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> <mvc:default-servlet-handler/> </beans>
6)在包**org.arpit.java2blog.controller** 中创建一个名为“HelloWorldController.java”的控制器
package org.arpit.java2blog.controller; import java.io.IOException; import org.apache.log4j.Logger; import org.arpit.java2blog.exception.CustomException; import org.springframework.stereotype.Controller; 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.servlet.ModelAndView; @Controller public class HelloWorldController { private static final Logger logger = Logger .getLogger(HelloWorldController.class); @RequestMapping("/helloworld/{helloType}") public ModelAndView hello(@PathVariable("helloType") String helloType) throws CustomException, IOException { String helloWorldMessage=""; if (helloType.equalsIgnoreCase("CustomException")) { throw new CustomException("Custom exception occured"); } else if (helloType.equalsIgnoreCase("IOException")) { throw new IOException(" IO exception occured"); } else { helloWorldMessage = "Hello world from java2blog!"; } return new ModelAndView("hello", "message", helloWorldMessage); } @ExceptionHandler(CustomException.class) public ModelAndView catchCustomException(CustomException ex) { ModelAndView model = new ModelAndView("Custom_Exception"); model.addObject("errorMessage", ex.getMessage()); return model; } @ExceptionHandler(IOException.class) public ModelAndView catchIOException(IOException ex) { ModelAndView model = new ModelAndView("IOException"); model.addObject("errorMessage", ex.getMessage()); return model; } }
package org.arpit.java2blog.controller; import java.io.IOException; import org.arpit.java2blog.exception.CustomException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView; @ControllerAdvice public class GlobalExceptionController { @ExceptionHandler(CustomException.class) public ModelAndView catchCustomException(CustomException ex) { ModelAndView model = new ModelAndView("Custom_Exception"); model.addObject("errorMessage", ex.getMessage()); return model; } @ExceptionHandler(IOException.class) public ModelAndView catchCustomException(IOException ex) { ModelAndView model = new ModelAndView("IOException"); model.addObject("errorMessage", ex.getMessage()); return model; } }
如您所见,我们用@ExceptionHandler 注释了两个方法,即catchCustomException 和catchIOException。这些方法将分别处理 CustomException 和 IOException 并且这些异常也可以被多个控制器抛出。
修改 index.jsp如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>HelloWorld</title> </head> <body> Hello World!! </body> </html>
在 /WEB-INF/ 文件夹中创建 Custom_Excepion.jsp 来处理 CustomException 异常。
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Custom Exception</title> </head> <body> ${errorMessage} </body> </html>
如下在 /WEB-INF 文件夹中创建 IOException.jsp 来处理 IOException。
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>IO Exception</title> </head> <body> ${errorMessage} </body> </html>
7) 是时候做 Maven 构建了。
右键单击项目-> 运行方式-> Maven 构建
8) 提供全新安装的目标(如下所示),然后单击运行
9) 右键单击项目->运行为->在服务器上运行
选择apache tomcat并点击finish
\10) 让我们点击以下 URL http://localhost:8080/SpringMVCControllerAdviceExample/helloworld/hello
如您所见,它与上面的 URL 工作正常。 现在让我们点击一些会引发异常的 URL,异常将由 @ControllerAdvice 类中的 @ExcpetionHandler 处理。
当您点击以下网址时。 http://localhost:8080/SpringMVCControllerAdviceExample/helloworld/CustomException
如您所见,当您点击上面的 URL 时,CustomException 被 @ControllerAdvice 类中的 catchCustomException 方法抛出和处理。
当您点击以下网址时。 http://localhost:8080/SpringMVCControllerAdviceExample/helloworld/IOException
如您所见,当您点击上面的 URL 时,CustomException 被 @ControllerAdvice 类中的 catchIOException 方法抛出和处理。
原文链接:https://codingdict.com/