使用 @ControllerAdvice 示例的 Spring MVC 异常处理


在这篇文章中,我们将看到如何在 Spring MVC 中使用 @ControllerAdvice 进行异常处理。在上一篇文章中,我们已经看到了如何使用 @ExceptionHandler 来处理异常,但是@ExceptionHandler 只能应用于一个控制器,但是如果您想全局处理异常,即跨多个控制器怎么办。您可以使用 @ControllerAdvice 全局处理异常。 让我们借助示例来理解这一点:

1) 在 Eclipse 中使用 maven创建一个 名为“SpringMVCControllerAdviceExample”的动态 Web 项目

Maven 依赖项

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>

Spring应用配置:

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

创建名为 GlobalExceptionController.java 的 ControllerAdvice

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 构建

Maven 在 Eclipse 中构建

8) 提供全新安装的目标(如下所示),然后单击运行

Maven 在 Eclipse 中构建

运行应用程序

9) 右键单击项目->运行为->在服务器上运行

选择apache tomcat并点击finish

img

\10) 让我们点击以下 URL http://localhost:8080/SpringMVCControllerAdviceExample/helloworld/hello

img

如您所见,它与上面的 URL 工作正常。 现在让我们点击一​​些会引发异常的 URL,异常将由 @ControllerAdvice 类中的 @ExcpetionHandler 处理。

当您点击以下网址时。 http://localhost:8080/SpringMVCControllerAdviceExample/helloworld/CustomException

img

如您所见,当您点击上面的 URL 时,CustomException 被 @ControllerAdvice 类中的 catchCustomException 方法抛出和处理。

当您点击以下网址时。 http://localhost:8080/SpringMVCControllerAdviceExample/helloworld/IOException

img

如您所见,当您点击上面的 URL 时,CustomException 被 @ControllerAdvice 类中的 catchIOException 方法抛出和处理。


原文链接:https://codingdict.com/