1. 概述
这篇文章会介绍几种在 Spring MVC 控制器中返回自定义 HTTP 状态码的方法。
为什么要自定义状态码?因为 HTTP 协议本身提供了丰富的语义,通过返回合适的状态码,可以让客户端更清楚地知道请求的结果,从而做出更合理的处理。比如,当请求出错时,不同的错误类型返回不同的错误码,客户端就可以展示对应的错误提示给用户。
⚠️ 本文不会介绍如何搭建 Spring MVC 项目,如果你还不熟悉基础环境,可以先参考 Spring MVC 教程。
2. 返回自定义状态码的方式
Spring 提供了三种主要方式返回自定义状态码:
- 使用
ResponseEntity
- 在异常类上使用
@ResponseStatus
注解 - 使用
@ControllerAdvice
+@ExceptionHandler
全局异常处理(本文不重点介绍,详见 这里)
✅ 这些方式不是互斥的,反而可以配合使用,提升代码的灵活性和可维护性。
2.1. 使用 ResponseEntity 返回状态码
这是最常见、最灵活的一种方式。在控制器中返回 ResponseEntity
对象,可以自由控制响应的状态码、头部信息和响应体。
示例代码如下:
@RequestMapping(value = "/controller", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity sendViaResponseEntity() {
return new ResponseEntity(HttpStatus.NOT_ACCEPTABLE);
}
当客户端发起 GET 请求访问 /controller
时,Spring 会返回一个 406 Not Acceptable
的状态码。
💡 这里我们随便选了一个状态码作为示例,实际开发中你可以返回任何合法的 HTTP 状态码(完整列表见 HTTP 状态码维基百科)。
2.2. 通过抛出异常返回状态码
另一种常见的做法是通过抛出异常,配合 @ResponseStatus
注解来返回特定状态码。
先看控制器方法:
@RequestMapping(value = "/exception", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity sendViaException() {
throw new ForbiddenException();
}
当访问 /exception
接口时,控制器会抛出一个自定义异常 ForbiddenException
:
@ResponseStatus(HttpStatus.FORBIDDEN)
public class ForbiddenException extends RuntimeException {}
这个异常类本身没有逻辑代码,所有“返回 403 状态码”的行为都由 @ResponseStatus
注解完成。
✅ 如果你希望返回时带上错误信息,可以这样写:
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason="To show an example of a custom message")
public class ForbiddenException extends RuntimeException {}
⚠️ 虽然技术上你可以让异常返回任意状态码,但从语义上讲,异常更适合用于返回错误类状态码(4xx 和 5xx),不要滥用。
3. 总结
这篇文章介绍了在 Spring MVC 控制器中返回自定义 HTTP 状态码的两种主要方式:
- ✅ 使用
ResponseEntity
灵活控制响应 - ✅ 使用
@ResponseStatus
注解搭配异常类返回特定状态码
示例代码可以在 GitHub 示例项目 中找到。