此版本仍在开发中,尚未被视为稳定版。如需最新稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

异常

@Controller@ControllerAdvice 类可以包含 @ExceptionHandler 方法,用于处理控制器方法抛出的异常。以下示例包含这样一个异常处理方法:spring-doc.cadn.net.cn

import java.io.IOException;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;

@Controller
public class SimpleController {

	@ExceptionHandler(IOException.class)
	public ResponseEntity<String> handle() {
		return ResponseEntity.internalServerError().body("Could not read file storage");
	}

}
import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.ExceptionHandler
import java.io.IOException

@Controller
class SimpleController {

	@ExceptionHandler(IOException::class)
	fun handle() : ResponseEntity<String> {
		return ResponseEntity.internalServerError().body("Could not read file storage")
	}
	
}

该异常可以匹配正在传播的顶层异常(即直接抛出的IOException),也可以匹配顶层包装异常中的直接原因(例如,被包装在IOException内部的IllegalStateException)。spring-doc.cadn.net.cn

为了匹配异常类型,建议将目标异常声明为方法参数,如上例所示。或者,也可以通过注解声明来缩小要匹配的异常类型范围。我们通常建议在方法参数签名中尽可能具体,并在使用相应顺序(order)进行优先级排序的 @ControllerAdvice 中声明主要的根异常映射。 详情请参见MVC 章节spring-doc.cadn.net.cn

WebFlux 中的 @ExceptionHandler 方法支持与 @RequestMapping 方法相同的参数和返回值类型,但与请求体(request body)和 @ModelAttribute 相关的方法参数除外。

Spring WebFlux 对 @ExceptionHandler 方法的支持由用于 @RequestMapping 方法的 HandlerAdapter 提供。详见 DispatcherHandler 以获取更多详情。spring-doc.cadn.net.cn

媒体类型映射

除了异常类型之外,@ExceptionHandler 方法还可以声明可生成的媒体类型。 这使得可以根据 HTTP 客户端请求的媒体类型(通常在 HTTP 请求头的“Accept”字段中指定)来细化错误响应。spring-doc.cadn.net.cn

应用程序可以在注解上直接声明可生成的媒体类型,用于同一异常类型:spring-doc.cadn.net.cn

@ExceptionHandler(produces = "application/json")
public ResponseEntity<ErrorMessage> handleJson(IllegalArgumentException exc) {
	return ResponseEntity.badRequest().body(new ErrorMessage(exc.getMessage(), 42));
}

@ExceptionHandler(produces = "text/html")
public String handle(IllegalArgumentException exc, Model model) {
	model.addAttribute("error", new ErrorMessage(exc.getMessage(), 42));
	return "errorView";
}
@ExceptionHandler(produces = ["application/json"])
fun handleJson(exc: IllegalArgumentException): ResponseEntity<ErrorMessage> {
	return ResponseEntity.badRequest().body(ErrorMessage(exc.message, 42))
}

@ExceptionHandler(produces = ["text/html"])
fun handle(exc: IllegalArgumentException, model: Model): String {
	model.addAttribute("error", ErrorMessage(exc.message, 42))
	return "errorView"
}

在这里,多个方法处理相同的异常类型,但不会被当作重复而拒绝。 相反,请求“application/json”的 API 客户端将收到一个 JSON 格式的错误,而浏览器则会获得一个 HTML 错误视图。 每个 @ExceptionHandler 注解可以声明多种可生成的媒体类型, 在错误处理阶段的内容协商将决定使用哪种内容类型。spring-doc.cadn.net.cn

方法参数

@ExceptionHandler 方法支持与 xref page 方法相同的方法参数,但请求体可能已被读取过了。spring-doc.cadn.net.cn

返回值

@ExceptionHandler 方法支持与 xref page 方法相同的返回值spring-doc.cadn.net.cn