ResponseEntity类

1. ResponseEntity 概述

ResponseEntity 是 Spring 框架中用于构建 HTTP 响应的类,它允许开发者灵活设置响应的状态码响应头部信息、以及响应体。它广泛用于 RESTful API 开发中,用于服务器向客户端返回各种响应结果。

@ResponseBody 不同,ResponseEntity 提供了对 HTTP 响应的更细粒度的控制,适用于需要设置自定义响应头、返回非 200 状态码(如 201 Created、400 Bad Request 等)或返回文件内容的场景。

2. ResponseEntity 的构成要素

2.1 HTTP 状态码

HTTP 状态码表示服务器对客户端请求的处理结果。ResponseEntity 提供了多种状态码支持,常见的状态码有:

  • 200 OK:请求成功,常用于返回正常的响应。
  • 201 Created:新资源成功创建,常用于 POST 请求。
  • 400 Bad Request:客户端请求有误,通常由于参数无效或请求格式错误。
  • 404 Not Found:请求的资源不存在。
  • 500 Internal Server Error:服务器内部错误,常用于处理请求时发生了未捕获的异常。

2.2 响应头

HTTP 响应头提供了关于响应体或服务器的元数据,常见的头部包括:

  • Content-Type:指定响应内容的媒体类型(如 application/jsontext/plain)。
  • Content-Disposition:用于指示响应体是否应该作为附件下载,或直接展示。
  • Cache-Control:指定缓存策略,如 no-cacheprivatemax-age
  • Location:用于重定向或指向新创建的资源(常用于 201 Created 响应)。

2.3 响应体

ResponseEntity 可以包含不同类型的响应体,Spring 会根据客户端的 Accept 请求头自动将响应体格式化为客户端期望的格式。常见的响应体包括:

  • 字符串text/plain
  • JSON 对象(application/json
  • XML 对象(application/xml
  • 文件(如 PDF、Excel 等)
  • 流式数据(如视频或音频)

3. ResponseEntity 的构建方式

3.1 构造函数创建 ResponseEntity

可以直接使用 ResponseEntity 的构造函数来设置状态码、响应头和响应体。

示例

ResponseEntity<String> response = new ResponseEntity<>("Hello, World!", HttpStatus.OK);
  • new ResponseEntity<>(body, status):第一个参数为响应体,第二个参数为状态码。这里设置了响应体为 "Hello, World!",状态码为 200 OK

3.2 静态方法构建 ResponseEntity

Spring 提供了多个静态方法,帮助开发者快速构建常见的响应。

3.2.1 ResponseEntity.ok()

用于返回状态码 200 OK 的响应。

ResponseEntity<String> response = ResponseEntity.ok("Operation successful");

3.2.2 ResponseEntity.badRequest()

用于返回 400 Bad Request 的响应,表示客户端请求错误。

ResponseEntity<String> response = ResponseEntity.badRequest().body("Invalid request");

3.2.3 ResponseEntity.notFound()

用于返回 404 Not Found 的响应,表示请求的资源未找到。

ResponseEntity<Void> response = ResponseEntity.notFound().build();

3.2.4 ResponseEntity.status()

用于构建任意 HTTP 状态码的响应,适用于需要返回不常见状态码的场景。

ResponseEntity<String> response = ResponseEntity.status(HttpStatus.CREATED).body("Resource Created");

4. 设置 HTTP 响应头

ResponseEntity 提供了灵活的 API 来设置 HTTP 响应头。开发者可以通过 header() 方法来设置响应头。

4.1 设置 Content-Type

ResponseEntity<String> response = ResponseEntity.ok()
    .header(HttpHeaders.CONTENT_TYPE, "application/json")
    .body("{\"message\": \"Hello, JSON\"}");
  • Content-Type:用于指定返回数据的媒体类型。在此例中,指定了返回 application/json 类型。

4.2 设置 Content-Disposition

Content-Disposition 常用于文件下载,告诉浏览器以附件形式下载文件。

ResponseEntity<Resource> downloadResponse = ResponseEntity.ok()
    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"file.txt\"")
    .body(resource);
  • attachment; filename="...":表示客户端应该以附件的形式下载文件,而不是直接显示文件内容。

4.3 设置 Cache-Control

Cache-Control 用于控制缓存策略。

ResponseEntity<String> noCacheResponse = ResponseEntity.ok()
    .header(HttpHeaders.CACHE_CONTROL, "no-cache")
    .body("No cache content");
  • no-cache:表示不允许客户端缓存此响应。

4.4 设置 Location

当返回 201 Created 响应时,通常会设置 Location 头部,指示新创建资源的 URL。

ResponseEntity<Void> createdResponse = ResponseEntity.status(HttpStatus.CREATED)
    .header(HttpHeaders.LOCATION, "/new-resource-url")
    .build();

5. 设置响应体

ResponseEntity 的响应体可以是字符串、对象、文件等各种数据格式。Spring 会自动根据客户端的 Accept 头来决定如何序列化返回对象。

5.1 返回字符串

ResponseEntity<String> response = ResponseEntity.ok("This is a plain text response");
  • 返回一个普通的字符串作为响应体。

5.2 返回对象(JSON 或 XML)

Spring 会自动将对象转换为 JSON(或根据请求头为 XML),无需手动处理对象的序列化。

@GetMapping("/user")
public ResponseEntity<User> getUser() {
    User user = new User("John", "Doe");
    return ResponseEntity.ok(user);
}
  • Spring 会自动将 User 对象转换为 JSON 格式返回。

5.3 返回文件

使用 ResponseEntity 可以方便地实现文件下载。

@GetMapping("/download/{filename}")
public ResponseEntity<Resource> downloadFile(@PathVariable String filename) {
    Path filePath = Paths.get("uploads").resolve(filename).normalize();
    Resource resource = new UrlResource(filePath.toUri());

    if (resource.exists()) {
        return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
            .body(resource);
    } else {
        return ResponseEntity.notFound().build();
    }
}
  • Resource:封装了文件内容,Content-Disposition 头部告诉客户端下载文件时应使用的文件名。

6. ResponseEntity 的常见应用场景

6.1 RESTful API

ResponseEntity 在 RESTful API 中用来返回不同的状态码和数据格式,帮助开发者处理各种请求结果。

@RestController
@RequestMapping("/users")
public class UserController {

    // 获取用户信息
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.findById(id);
        if (user == null) {
            return ResponseEntity.notFound().build();  // 返回 404 Not Found
        }
        return ResponseEntity.ok(user);  // 返回 200 OK 和用户信息
    }

    // 创建用户
    @PostMapping
    public ResponseEntity<String> createUser(@RequestBody User user) {
        userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body("User created");  // 返回 201 Created
    }
}

6.2 文件下载

ResponseEntity 可以用于文件下载的场景,通过设置合适的 Content-Disposition 头部,可以让浏览器提示下载文件。

@GetMapping("/download/{filename}")
public ResponseEntity<Resource> downloadFile(@PathVariable String filename) {
    Path filePath = Paths.get("uploads").resolve(filename).normalize();
    Resource resource = new UrlResource(filePath.toUri());

    if (resource.exists()) {
        return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
            .body(resource);
    } else {
        return ResponseEntity.notFound().build();
    }
}

6.3 异常处理

在处理异常时,ResponseEntity 可以返回合适的状态码和错误信息。

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleNotFound(ResourceNotFoundException e) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());  // 返回 404 和错误信息
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleGeneralException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An unexpected error occurred");
    }
}

7. 总结

  • ResponseEntity 是用于构建 HTTP 响应的类,它允许开发者灵活控制 HTTP 响应的状态码、头部信息和响应体内容。
  • 构建方式:可以通过构造函数和静态方法创建 ResponseEntity,其中静态方法如 ok()badRequest()notFound() 便于处理常见的状态码。
  • 设置响应头:可以设置常见的 Content-TypeContent-DispositionCache-Control 等头部,控制响应体的处理方式。
  • 响应体类型:可以返回字符串、对象(自动转换为 JSON 或 XML)、文件(通过 Resource)、以及其他类型的流式数据。
  • 应用场景ResponseEntity 广泛用于 RESTful API、文件下载、以及异常处理。
上一篇:网络安全中的日志审计:为何至关重要?


下一篇:这几次比赛题解-T