Spring Boot @ExceptionHandler
最后修改于 2023 年 7 月 16 日
Spring Boot @ExceptionHandler 教程展示了如何使用 Spring @ExceptionHandler 处理异常。
Spring 是一个流行的 Java 应用程序框架,而 Spring Boot 是 Spring 的一个演进,它有助于轻松创建独立的、生产级的基于 Spring 的应用程序。
@ExceptionHandler 是一个用于在特定处理程序类或处理程序方法中处理异常的注解。在 Servlet 环境中,我们可以将 @ExceptionHandler 注解与 @ResponseStatus 结合使用,以定义 HTTP 响应的响应状态。
Spring Boot @ExceptionHandler 示例
在以下应用程序中,我们演示了 @ExceptionHandler 的用法。主页上的一个 HTML 链接调用一个控制器的某个方法,该方法要么返回数据,要么抛出异常。
build.gradle
...
src
├── 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.ftlh
└── test
├── java
└── resources
这是 Spring 应用程序的项目结构。
plugins {
id 'org.springframework.boot' version '3.1.1'
id 'io.spring.dependency-management' version '1.1.0'
id 'java'
}
group = 'com.zetcode'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-freemarker'
}
这是 Gradle 构建文件。spring-boot-starter-freemarker 是 Freemarker 模板引擎的依赖项。
package com.zetcode.controller;
import com.zetcode.exception.MyDataException;
import com.zetcode.service.IDataService;
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;
@Controller
public class MyController {
private final IDataService dataService;
public MyController(IDataService dataService) {
this.dataService = 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 页面。
package com.zetcode.exception;
public class MyDataException extends RuntimeException {
public MyDataException(String message) {
super(message);
}
}
我们定义了一个自定义的 MyDataException。
package com.zetcode.service;
import java.util.List;
public interface IDataService {
List<String> findAll();
}
IDataService 包含契约方法。
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;
@Service
public 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 的 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;
如果没有异常,我们返回一个字符串列表。
<!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>
这是主页。它包含一个链接,该链接调用我们的控制器方法来获取一些数据。
<!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 时,它会显示出来。
<!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><td>${val}</td></li>
</#list>
</ul>
</body>
</html>
showData.ftlh 是一个 Freemarker 模板文件,它在 HTML 列表中显示所有检索到的数据。
package com.zetcode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Application 是引导 Spring Boot 应用程序的入口点。
在本文中,我们展示了如何使用 @ExceptionHandler 在 Spring 应用程序中处理异常。