使用 Spring ResponseEntity 处理 HTTP 响应
1、概览
本文将带你了解如何使用 ResponseEntity
设置 HTTP 响应的 Body、Status 和 Header。
2、ResponseEntity
ResponseEntity
表示整个 HTTP 响应:状态码、Header 和 Body。因此,可以用它来完全配置 HTTP 响应。只需从端点返回它,Spring 就会处理接下来的所有事情。
ResponseEntity
是一个泛型类。因此,可以使用任何类型作为响应体:
@GetMapping("/hello")
ResponseEntity<String> hello() {
return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}
通过编程式,可以针对不同情况返回不同的 HTTP 状态码:
@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); // 400
}
return new ResponseEntity<>(
"Your age is " + calculateAge(yearOfBirth),
HttpStatus.OK); // 200s
}
还可以设置 HTTP 响应头:
@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "foo");
return new ResponseEntity<>(
"Custom header set", headers, HttpStatus.OK);
}
ResponseEntity
还提供了两个嵌套的 Builder 接口:HeadersBuilder
及其子接口 BodyBuilder
。可以通过 ResponseEntity
的静态方法访问它们。
如下,设置 200 响应并且指定响应体:
@GetMapping("/hello")
ResponseEntity<String> hello() {
return ResponseEntity.ok("Hello World!");
}
对于最常用的 HTTP 状态码,都提供了静态方法:
BodyBuilder accepted();
BodyBuilder badRequest();
BodyBuilder created(java.net.URI location);
HeadersBuilder<?> noContent();
HeadersBuilder<?> notFound();
BodyBuilder ok();
还可以使用 BodyBuilder status(HttpStatus status)
和 BodyBuilder status(int status)
方法来设置其他 HTTP 状态码。
可以通过 ResponseEntity<T> BodyBuilder.body(T body)
设置 HTTP 响应体:
@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));
}
还可以设置自定义 Header:
@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
return ResponseEntity.ok()
.header("Custom-Header", "foo")
.body("Custom header set");
}
由于 BodyBuilder.body()
返回的是 ResponseEntity
而不是 BodyBuilder
,所以它应该最后调用。
注意,使用 HeaderBuilder
时,不能设置响应体的任何属性。
3、替代方案
3.1、@ResponseBody
在经典的 Spring MVC 应用中,端点通常会返回已渲染的 HTML 页面。有时,只需要返回实际数据;例如,返回 JSON 数据。
在这种情况下,可以用 @ResponseBody
来标记 Handler 方法,这样 Spring 就会将该方法的结果值视为 HTTP 响应体本身。
3.2、@ResponseStatus
当端点成功返回时,Spring 会提供 HTTP 200(OK)响应。如果端点抛出异常,Spring 会寻找一个异常 Handler,告知使用哪种 HTTP 状态。
可以用 @ResponseStatus
标记这些方法,这样 Spring 就会返回自定义的 HTTP 状态码。
3.3、直接操作 Response
Spring 还允许我们直接访问 javax.servlet.http.HttpServletResponse
对象。
只需将其声明为方法参数即可:
@GetMapping("/manual")
void manual(HttpServletResponse response) throws IOException {
response.setHeader("Custom-Header", "foo");
response.setStatus(200);
response.getWriter().println("Hello World!");
}
4、总结
本文介绍了如何在 Spring 中通过 ResponseEntity 来操作响应,以及可代替 ResponseEntity 的方式有哪些。
Ref:https://www.baeldung.com/spring-response-entity