Spring @RequestBody 和@ResponseBody注解
1.简介
在这个快速教程中,我们简要概述了 Spring @RequestBody和*@ResponseBody*注解。
2. @RequestBody
简单地说,@RequestBody注解将HttpRequest主体映射到传输或域对象,从而将入站HttpRequest主体自动反序列化到 Java 对象上。
首先,我们来看一个 Spring 控制器方法:
@PostMapping("/request")
public ResponseEntity postController(
@RequestBody LoginForm loginForm) {
exampleService.fakeAuthenticate(loginForm);
return ResponseEntity.ok(HttpStatus.OK);
}
假设指定了适当的类型,Spring 会自动将 JSON 反序列化为 Java 类型。 默认情况下,我们使用@RequestBody*注解注解的类型必须对应于从我们的客户端控制器发送的 JSON:*
public class LoginForm {
private String username;
private String password;
// ...
}
在这里,我们用来表示HttpRequest主体的对象映射到我们的LoginForm对象。 让我们使用 CURL 进行测试:
curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data
'{"username": "johnny", "password": "password"}' "https://localhost:8080/.../request"
这就是使用*@RequestBody*注解的 Spring REST API 和 Angular 客户端所需要的全部内容。
3. @ResponseBody
@ResponseBody注解告诉控制器返回的对象自动序列化为 JSON 并传回HttpResponse对象。 假设我们有一个自定义的Response对象:
public class ResponseTransfer {
private String text;
// standard getters/setters
}
接下来,可以实现关联的控制器:
@Controller
@RequestMapping("/post")
public class ExamplePostController {
@Autowired
ExampleService exampleService;
@PostMapping("/response")
@ResponseBody
public ResponseTransfer postResponseController(
@RequestBody LoginForm loginForm) {
return new ResponseTransfer("Thanks For Posting!!!");
}
}
在我们浏览器的开发者控制台中或者使用 Postman 之类的工具,我们可以看到如下响应:
{"text":"Thanks For Posting!!!"}
*请记住,我们不需要使用@ResponseBody注解来注解@RestController-*注解的控制器,**因为 Spring 默认会这样做。
3.1. 设置内容类型
当我们使用*@ResponseBody*注解时,我们仍然能够显式地设置我们的方法返回的内容类型。
为此,我们可以使用@RequestMapping的produces 属性。**请注意,@PostMapping、@GetMapping等注解定义了该参数的别名。
现在让我们添加一个发送 JSON 响应的处理点:
@PostMapping(value = "/content", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseTransfer postResponseJsonContent(
@RequestBody LoginForm loginForm) {
return new ResponseTransfer("JSON Content!");
}
在示例中,我们使用了MediaType.APPLICATION_JSON_VALUE常量。或者,我们可以直接使用application/json。 接下来,让我们实现一个新方法,映射到相同的*/content*路径,但返回 XML 内容:
@PostMapping(value = "/content", produces = MediaType.APPLICATION_XML_VALUE)
@ResponseBody
public ResponseTransfer postResponseXmlContent(
@RequestBody LoginForm loginForm) {
return new ResponseTransfer("XML Content!");
}
现在,根据请求标头中发送的Accept参数的值,我们将得到不同的响应。 让我们看看它的实际效果:
curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data
'{"username": "johnny", "password": "password"}' "https://localhost:8080/.../content"
CURL 命令返回 JSON 响应:
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 20 Feb 2020 19:43:06 GMT
{"text":"JSON Content!"}
现在,让我们更改Accept参数:
curl -i \
-H "Accept: application/xml" \
-H "Content-Type:application/json" \
-X POST --data
'{"username": "johnny", "password": "password"}' "https://localhost:8080/.../content"
正如预期的那样,这次我们得到了一个 XML 内容:
HTTP/1.1 200
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Thu, 20 Feb 2020 19:43:19 GMT
<ResponseTransfer><text>XML Content!</text></ResponseTransfer>