1. 概述

本文将深入探讨在 Spring Boot 应用中使用 HttpStatusCode 的方法,重点分析 3.3.3 版本引入的最新增强特性。通过这些改进,HttpStatusCode 已集成到 HttpStatus 实现中,简化了 HTTP 状态码的处理流程

这些改进的核心目标是提供更灵活可靠的方式处理标准及自定义 HTTP 状态码,在保持向后兼容的同时,为 HTTP 响应处理带来更高的灵活性和可扩展性。

2. HttpStatus 枚举详解

在 Spring 3.3.3 之前,HTTP 状态码通过 HttpStatus 中的枚举表示。这种方式限制了自定义或非标准 HTTP 状态码的使用,因为枚举本质上是固定的预定义值集合。

尽管 HttpStatus 类未被弃用,但部分返回原始整型状态码的枚举和方法(如 getRawStatusCode()rawStatusCode())现已标记为弃用。不过,使用 @ResponseStatus 注解提升代码可读性仍是推荐做法。

我们也可以结合 HttpStatusHttpStatusCode 实现更灵活的 HTTP 响应管理:

@GetMapping("/exception")
public ResponseEntity<String> resourceNotFound() {
    HttpStatus statusCode = HttpStatus.NOT_FOUND;
    if (statusCode.is4xxClientError()) {
        return new ResponseEntity<>("Resource not found", HttpStatusCode.valueOf(404));
    }
    return new ResponseEntity<>("Resource found", HttpStatusCode.valueOf(200));
}

3. HttpStatusCode 接口解析

HttpStatusCode 接口专为支持 HttpStatus 预定义值之外的自定义状态码设计,包含 8 个实例方法:

  • is1xxInformational()
  • is2xxSuccessful()
  • is3xxRedirection()
  • is4xxClientError()
  • is5xxServerError()
  • isError()
  • isSameCodeAs(HttpStatusCode other)
  • value()

这些方法不仅增强了处理不同 HTTP 状态的灵活性,还简化了响应类别检查流程,提升了状态码管理的清晰度和效率。

以下是一个实际应用示例:

@GetMapping("/resource")
public ResponseEntity successStatusCode() {
    HttpStatusCode statusCode = HttpStatusCode.valueOf(200);
    if (statusCode.is2xxSuccessful()) {
        return new ResponseEntity("Success", statusCode);
    }

    return new ResponseEntity("Moved Permanently", HttpStatusCode.valueOf(301));
}

3.1. 静态方法 valueOf(int)

该方法根据给定的 int 值返回 HttpStatusCode 对象。**输入参数必须是三位正数,否则将抛出 IllegalArgumentException**。

valueOf() 将状态码映射到 HttpStatus 中的对应枚举值。若无匹配项,则默认返回 DefaultHttpStatusCode 实例。

DefaultHttpStatusCode 类实现了 HttpStatusCode 接口,其 value() 方法直接返回初始化时使用的原始整型值。这种设计确保了所有 HTTP 状态码(无论是自定义还是非标准)都能便捷处理:

@GetMapping("/custom-exception")
public ResponseEntity<String> goneStatusCode() {
    throw new ResourceGoneException("Resource Gone", HttpStatusCode.valueOf(410));
}

4. 在自定义异常中使用 HttpStatusCode

接下来我们探讨如何在 ExceptionHandler 中结合自定义异常使用 HttpStatusCode。我们将使用 @ControllerAdvice 注解实现全局异常处理,并通过 @ExceptionHandler 注解管理自定义异常实例。

这种机制在 Spring MVC 应用中实现了异常处理的集中化,使代码更简洁且易于维护

4.1. @ControllerAdvice@ExceptionHandler 实践

@ControllerAdvice 负责全局异常处理,而 @ExceptionHandler 则管理自定义异常实例,返回包含异常消息和状态码的一致性 HTTP 响应。

实际应用示例:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(CustomException.class)
    public ResponseEntity<String> handleGoneException(CustomException e) {
        return new ResponseEntity<>(e.getMessage(), e.getStatusCode());
    }
}

4.2. 自定义异常实现

下面定义一个继承 RuntimeExceptionCustomException 类,包含 HttpStatusCode 字段,支持自定义消息和 HTTP 状态码,实现更精确的异常处理:

public class CustomException extends RuntimeException {

    private final HttpStatusCode statusCode;

    public CustomException(String message, HttpStatusCode statusCode) {
        super(message);
        this.statusCode = statusCode;
    }

    public HttpStatusCode getStatusCode() {
        return statusCode;
    }
}

5. 总结

HttpStatus 枚举包含有限的标准 HTTP 状态码集合,在旧版 Spring 中能满足大多数场景需求。但其缺乏定义自定义状态码的灵活性。

Spring Boot 3.3.3 引入的 HttpStatusCode 解决了这一限制,允许我们定义自定义状态码。它提供了更灵活的状态码处理方式,通过 is2xxSuccessful()is3xxRedirection() 等实例方法,实现了对响应处理更精细的控制。

本文所有完整示例代码可在 GitHub 获取。


原始标题:Migrate HttpStatus to HttpStatusCode in Spring Boot 3 | Baeldung