使用 Spring ResponseEntity 操控 HTTP 響應

REST,Spring MVC
Remote
0
10:48 AM · Dec 01 ,2025

1. 簡介

使用 Spring,我們通常有多種方法可以實現相同的目標,包括調整 HTTP 響應。

在本簡短教程中,我們將學習如何使用 ResponseEntity 設置 HTTP 響應的 body、狀態碼和 headers。

2. ResponseEntity

ResponseEntity represents the whole HTTP response: status code, headers, and body. As a result, we can use it to fully configure the HTTP response.

If we want to use it, we have to return it from the endpoint; Spring takes care of the rest.

ResponseEntity is a generic type. Consequently, we can use any type as the response body:

@GetMapping("/hello")
ResponseEntity<String> hello() {
    return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}

Since we specify the response status programmatically, we can return with different status codes for different scenarios:

@GetMapping("/age")
ResponseEntity<String> age(
  @RequestParam("yearOfBirth") int yearOfBirth) {
 
    if (isInFuture(yearOfBirth)) {
        return new ResponseEntity<>(
          "Year of birth cannot be in the future", 
          HttpStatus.BAD_REQUEST);
    }

    return new ResponseEntity<>(
      "Your age is " + calculateAge(yearOfBirth), 
      HttpStatus.OK);
}

Additionally, we can set HTTP headers:

@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
    HttpHeaders headers = new HttpHeaders();
    headers.add("Custom-Header", "foo");
        
    return new ResponseEntity<>(
      "Custom header set", headers, HttpStatus.OK);
}

Furthermore, ResponseEntity provides two nested builder interfaces: HeaderBuilder and its subinterface, BodyBuilder. Therefore, we can access their capabilities through the static methods of ResponseEntity.

The simplest case is a response with a body and HTTP 200 response code:

@GetMapping("/hello")
ResponseEntity<String> hello() {
    return ResponseEntity.ok("Hello World!");
}

For the most popular HTTP status codes we get static methods:

BodyBuilder accepted();
BodyBuilder badRequest();
BodyBuilder created(java.net.URI location);
HeadersBuilder<?> noContent();
HeadersBuilder<?> notFound();
BodyBuilder ok();

In addition, we can use the BodyBuilder status(HttpStatus status) and the BodyBuilder status(int status) methods to set any HTTP status.

Finally, with BodyBuilder.body(T body) we can set the HTTP response body:

@GetMapping("/age")
ResponseEntity<String> age(@RequestParam("yearOfBirth") int yearOfBirth) {
    if (isInFuture(yearOfBirth)) {
        return ResponseEntity.badRequest()
            .body("Year of birth cannot be in the future");
    }

    return ResponseEntity.status(HttpStatus.OK)
        .body("Your age is " + calculateAge(yearOfBirth));
}

We can also set custom headers:

@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
    return ResponseEntity.ok()
        .header("Custom-Header", "foo")
        .body("Custom header set");
}

SinceBodyBuilder.body() returns a ResponseEntity instead of BodyBuilder, it should be the last call.

Note that with HeaderBuilder we can’t set any properties of the response body.

While returning ResponseEntity object from the controller, we might get an exception or error while processing the request and would like to return error-related information to the user represented as some other type, let’s say E.

Spring 3.2 brings support for a global @ControllerAdvice with the new @ExceptionHandler annotation, which handles these kinds of scenarios. For in-depth details, refer to our existing article here.

While ResponseEntity is very powerful, we shouldn’t overuse it. In simple cases, there are other options that satisfy our needs and they result in much cleaner code.

3. 替代方案

3.1. @ResponseBody

在經典的 Spring MVC 應用中,端點通常返回渲染後的 HTML 頁面。有時我們只需要返回實際的數據,例如,當我們使用端點與 AJAX 一起時。

在這種情況下,我們可以標記請求處理方法為 @ResponseBody,Spring 會將方法的返回值視為 HTTP 響應體本身。

有關更多信息,這篇文章是一個不錯的起點。

3.2. @ResponseStatus

當端點成功返回時,Spring 提供 HTTP 200 (OK) 響應。如果端點拋出異常,Spring 會查找異常處理程序,以確定應使用哪個 HTTP 狀態碼。

我們可以標記這些方法為 @ResponseStatus,因此 Spring 會返回帶有自定義 HTTP 狀態碼。

有關更多示例,請訪問我們關於自定義狀態碼的文章。

3.3. 直接操縱響應

Spring 還允許我們直接訪問 jakarta.servlet.http.HttpServletResponse 對象;我們只需要將其聲明為方法參數:

@GetMapping("/manual")
void manual(HttpServletResponse response) throws IOException {
    response.setHeader("Custom-Header", "foo");
    response.setStatus(200);
    response.getWriter().println("Hello World!");
}

由於 Spring 提供了抽象和在底層實現之上的一些額外功能,因此我們不應以這種方式操縱響應。

4. 結論

在本文中,我們探討了多種方法來操縱 Spring 中的 HTTP 響應,並分析了它們的優缺點。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.