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 {@Autowiredprivate 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的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 {@Overridepublic 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的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 应用中处理异常。 您可能也对相关教程感兴趣: Spring Boot Flash 属性教程, Spring Boot @ResponseStatus教程, Spring Boot @PathVariable教程, Spring Boot @RequestParam教程, Java 教程,或显示所有 Spring Boot 教程。
