Spring Boot @ExceptionHandler 教程展示了如何使用 Spring @ExceptionHandler 处理异常。
Spring 是流行的 Java 应用框架,而 Spring Boot 是 Spring 的演进,可以帮助轻松地创建独立的,生产级的基于 Spring 的应用。
@ExceptionHandler是用于在特定处理程序类或处理程序方法中处理异常的注解。 在 Servlet 环境中,我们可以将@ExceptionHandler注解与@ResponseStatus结合起来以定义 HTTP 响应的响应状态。
Spring Boot @ExceptionHandler示例
在以下应用中,我们演示@ExceptionHandler的用法。 主页中的 HTML 链接调用控制器的方法,该方法将返回数据或引发异常。
pom.xmlsrc├── main│ ├── java│ │ └── com│ │ └── zetcode│ │ ├── Application.java│ │ ├── controller│ │ │ └── MyController.java│ │ ├── exception│ │ │ └── MyDataException.java│ │ └── service│ │ ├── IDataService.java│ │ └── MyDataService.java│ └── resources│ ├── static│ │ ├── index.html│ │ └── showError.html│ └── templates│ └── showData.ftl└── test └── java
这是 Spring 应用的项目结构。
pom.xml
<?xml version="1.0" encoding="UTF-8"?><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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zetcode</groupId> <artifactId>springbootexceptionhandlerex</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>
这是 Maven pom.xml文件。 spring-boot-starter-freemarker是 Freemarker 模板引擎的依赖项; spring-boot-maven-plugin将 Spring 应用打包到可执行的 JAR 或 WAR 归档文件中。
com/zetcode/controller/MyController.java
package com.zetcode.controller;import com.zetcode.exception.MyDataException;import com.zetcode.service.IDataService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import java.util.HashMap;import java.util.Map;@Controllerpublic class MyController { @Autowired private IDataService dataService; @RequestMapping(value = "/getData") public ModelAndView getData() { var data = dataService.findAll(); Map<String, Object> params = new HashMap<>(); params.put("values", data); return new ModelAndView("showData", params); } @ExceptionHandler(MyDataException.class) public String handleError(MyDataException e) { return "redirect:/showError.html"; }}MyController's getData()方法调用服务方法,并将检索到的数据存储到列表中。 数据被发送到showData视图。 如果是MyDataException,则控制器将重定向到错误页面。
@ExceptionHandler(MyDataException.class)public String handleError(MyDataException e) { return "redirect:/showError.html";}handleError()用@ExceptionHandler装饰。 MyDataException的处理程序已激活。 在方法的主体中,我们重定向到showError.html页面。
com/zetcode/exception/MyDataException.java
package com.zetcode.exception;public class MyDataException extends RuntimeException { public MyDataException(String message) { super(message); }}我们定义一个自定义MyDataException。
com/zetcode/service/IDataService.java
package com.zetcode.service;import java.util.List;public interface IDataService { List<String> findAll();}IDataService包含合同方法。
com/zetcode/service/MyDataService.java
package com.zetcode.service;import com.zetcode.exception.MyDataException;import java.util.ArrayList;import java.util.List;import java.util.Random;import org.springframework.stereotype.Service;@Servicepublic class MyDataService implements IDataService { @Override public List<String> findAll() { var r = new Random(); if (r.nextBoolean()) { throw new MyDataException("Failed to retrieve data"); } var data = new ArrayList<String>(); data.add("yellow moon"); data.add("brisk pace"); data.add("empty bottle"); data.add("beautiful weather"); return data; }}MyDataService实现IDataService's findAll()方法。 该方法返回数据或抛出MyDataException。
var r = new Random();if (r.nextBoolean()) { throw new MyDataException("Failed to retrieve data");}findAll()方法随机抛出MyDataException。 然后在控制器中处理异常。
var data = new ArrayList<>();data.add("yellow moon");data.add("brisk pace");data.add("empty bottle");data.add("beautiful weather");return data;如果没有例外,我们将返回一个字符串列表。
resources/static/index.html
<!DOCTYPE html><html> <head> <title>Home page</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <a href="/getData">Get data</a> </body></html>
这是主页。 它包含一个链接,该链接调用我们的控制器方法以获取一些数据。
resources/static/showError.html
<!DOCTYPE html><html> <head> <title>Error</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <p>Failed to retrieve data</p> </body></html>
这是一个错误页面。 抛出MyDataException时显示。
resources/templates/showData.ftl
<!DOCTYPE html><html> <head> <title>Data</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h2>Data</h2> <ul> <#list values as val> <li>${val}</td> </#list> </ul> </body></html>showData.ftl是一个 Freemarker 模板文件,它在 HTML 列表中显示所有检索到的数据。
com/zetcode/Application.java
package com.zetcode;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}Application是引导 Spring Boot 应用的入口点。
在本教程中,我们展示了如何使用@ExceptionHandler在 Spring 应用中处理异常。
