Spring Boot Controller 返回指定的 HTTP 状态码

在构建 RESTful API 时,HTTP 状态码是非常重要的信息,它能够向客户端传达请求的处理结果。在 Spring Boot 的 Controller 中返回指定的 HTTP 状态码是一个常见需求。本文将探讨如何在 Spring Boot Controller 中实现这一功能,并提供相关的代码示例。

什么是 HTTP 状态码?

HTTP 状态码是一种标准化的数字代码,帮助服务器和客户端之间进行通信。每一个状态码都有其特定的含义,比如:

  • 200 OK: 请求成功。
  • 201 Created: 成功创建资源。
  • 400 Bad Request: 请求无效。
  • 404 Not Found: 请求的资源未找到。
  • 500 Internal Server Error: 服务器内部错误。

通过返回不同的 HTTP 状态码,服务器可以告诉客户端请求的处理结果,这对调试和用户体验都至关重要。

在 Spring Boot Controller 中返回状态码

Spring Boot 提供了灵活的机制来返回 HTTP 状态码。我们通常会使用 ResponseEntity 对象来定制响应的内容和状态码。以下是一个简单的示例:

@RestController
@RequestMapping("/api")
public class MyController {

    @GetMapping("/resource/{id}")
    public ResponseEntity<Resource> getResource(@PathVariable String id) {
        Resource resource = findResourceById(id);

        if (resource != null) {
            return ResponseEntity.ok(resource); // 返回200 OK
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); // 返回404 Not Found
        }
    }

    @PostMapping("/resource")
    public ResponseEntity<Resource> createResource(@RequestBody Resource resource) {
        Resource createdResource = saveResource(resource);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdResource); // 返回201 Created
    }
}

上述代码中,getResource 方法根据 ID 查找资源。如果资源存在,则返回 200 状态码以及资源对象;如果资源不存在,则返回 404 状态码。createResource 方法用于创建新资源,成功后返回 201 状态码。

使用 @ResponseStatus 注解

在某些情况下,我们可以使用 @ResponseStatus 注解直接指定 API 方法返回的 HTTP 状态码。例如:

@RestController
@RequestMapping("/api")
public class MyController {

    @GetMapping("/resource/{id}")
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Resource getResource(@PathVariable String id) {
        Resource resource = findResourceById(id);
        if (resource == null) {
            throw new ResourceNotFoundException("Resource not found"); // 自定义异常
        }
        return resource; // 返回200 OK
    }
}

在这个例子中,如果资源未找到,我们将抛出一个自定义的异常,并由 Spring Boot 捕获并返回指定的状态码。

自定义异常处理

在生产环境中,我们通常需要对异常进行更加细致的处理。例如,我们可以创建一个全局异常处理器,使用 @ControllerAdvice 注解来集中处理异常:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handleResourceNotFound(ResourceNotFoundException ex) {
        return ex.getMessage(); // 返回404 Not Found
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handleGenericException(Exception ex) {
        return "An error occurred"; // 返回500 Internal Server Error
    }
}

通过这种方式,我们可以将异常处理与业务逻辑区分开来,使代码更加整洁,并且可以统一管理所有的异常处理逻辑。

使用序列图说明请求流程

为了帮助理解,在这里我们用一个序列图来展示客户端与服务器的交互流程:

sequenceDiagram
    participant Client
    participant Controller
    participant Service

    Client->>Controller: GET /api/resource/1
    Controller->>Service: findResourceById(1)
    Service-->>Controller: Resource found
    Controller-->>Client: 200 OK + Resource data

    Client->>Controller: GET /api/resource/999
    Controller->>Service: findResourceById(999)
    Service-->>Controller: null
    Controller-->>Client: 404 Not Found

这个序列图描述了客户端发送请求到 Spring Boot Controller 的流程,显示如何根据资源的存在与否返回不同的 HTTP 状态码。

总结

本文介绍了如何在 Spring Boot Controller 中返回指定的 HTTP 状态码,包括使用 ResponseEntity@ResponseStatus 注解和全局异常处理器等方式。通过合理使用这些功能,我们不仅可以提高 API 的可用性,还能为前端开发者提供清晰的信息,使他们能够更好地处理不同的请求状态。

了解并正确使用 HTTP 状态码,对于构建高质量的 RESTful API 至关重要。希望本文能帮助你更好地理解这一概念,并在实际开发中得心应手。