Spring’s RequestBody and ResponseBody Annotations – Spring的RequestBody和ResponseBody注解

最后修改: 2017年 9月 12日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

In this quick tutorial, we provide a concise overview of the Spring @RequestBody and @ResponseBody annotations.

在这个快速教程中,我们对Spring的@RequestBody@ResponseBody注解进行了简要的概述。

2. @RequestBody

2.@RequestBody

Simply put, the @RequestBody annotation maps the HttpRequest body to a transfer or domain object, enabling automatic deserialization of the inbound HttpRequest body onto a Java object.

简单地说, @RequestBody注解将HttpRequest体映射到传输或域对象上,使入站的HttpRequest体自动反序列化到一个Java对象上。

First, let’s have a look at a Spring controller method:

首先,让我们看一下Spring控制器的方法。

@PostMapping("/request")
public ResponseEntity postController(
  @RequestBody LoginForm loginForm) {
 
    exampleService.fakeAuthenticate(loginForm);
    return ResponseEntity.ok(HttpStatus.OK);
}

Spring automatically deserializes the JSON into a Java type, assuming an appropriate one is specified.

Spring会自动将JSON反序列化为一个Java类型,前提是指定了一个合适的类型。

By default, the type we annotate with the @RequestBody annotation must correspond to the JSON sent from our client-side controller:

默认情况下,我们用@RequestBody注解的类型必须对应于从我们的客户端控制器发送的JSON:

public class LoginForm {
    private String username;
    private String password;
    // ...
}

Here, the object we use to represent the HttpRequest body maps to our LoginForm object.

这里,我们用来表示HttpRequest体的对象映射到我们的LoginForm对象。

Let’s test this using CURL:

让我们用CURL来测试一下。

curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data 
  '{"username": "johnny", "password": "password"}' "https://localhost:8080/.../request"

This is all we need for a Spring REST API and an Angular client using the @RequestBody annotation.

这就是我们对Spring REST API和使用@RequestBody注解的Angular客户端的所有需求。

3. @ResponseBody

3.@ResponseBody

The @ResponseBody annotation tells a controller that the object returned is automatically serialized into JSON and passed back into the HttpResponse object.

@ResponseBody注解告诉控制器,返回的对象被自动序列化为JSON并传回HttpResponse对象中。

Suppose we have a custom Response object:

假设我们有一个自定义的Response对象。

public class ResponseTransfer {
    private String text; 
    
    // standard getters/setters
}

Next, the associated controller can be implemented:

接下来,可以实现相关的控制器。

@Controller
@RequestMapping("/post")
public class ExamplePostController {

    @Autowired
    ExampleService exampleService;

    @PostMapping("/response")
    @ResponseBody
    public ResponseTransfer postResponseController(
      @RequestBody LoginForm loginForm) {
        return new ResponseTransfer("Thanks For Posting!!!");
     }
}

In the developer console of our browser or using a tool like Postman, we can see the following response:

在我们浏览器的开发者控制台或使用像Postman这样的工具,我们可以看到以下响应。

{"text":"Thanks For Posting!!!"}

Remember, we don’t need to annotate the @RestController-annotated controllers with the @ResponseBody annotation since Spring does it by default.

记住,我们不需要用@RestController-注解来注解@ResponseBody的控制器,因为Spring默认这样做。

3.1. Setting the Content Type

3.1.设置内容类型

When we use the @ResponseBody annotation, we’re still able to explicitly set the content type that our method returns.

当我们使用@ResponseBody注解时,我们仍然能够明确地设置我们的方法返回的内容类型。

For that, we can use the @RequestMapping‘s produces attribute. Note that annotations like @PostMapping, @GetMapping, etc. define aliases for that parameter.

为此,我们可以使用@RequestMappingproduces属性。注意,像@PostMapping@GetMapping等注释为该参数定义了别名。

Let’s now add a new endpoint that sends a JSON response:

现在让我们添加一个新的端点,发送一个JSON响应。

@PostMapping(value = "/content", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseTransfer postResponseJsonContent(
  @RequestBody LoginForm loginForm) {
    return new ResponseTransfer("JSON Content!");
}

In the example, we used the MediaType.APPLICATION_JSON_VALUE constant. Alternatively, we can use application/json directly.

在这个例子中,我们使用了MediaType.APPLICATION_JSON_VALUE常量。另外,我们也可以直接使用application/json

Next, let’s implement a new method, mapped to the same /content path, but returning XML content instead:

接下来,让我们实现一个新的方法,映射到相同的/content路径,但返回XML内容。

@PostMapping(value = "/content", produces = MediaType.APPLICATION_XML_VALUE)
@ResponseBody
public ResponseTransfer postResponseXmlContent(
  @RequestBody LoginForm loginForm) {
    return new ResponseTransfer("XML Content!");
}

Now, depending on the value of an Accept parameter sent in the request’s header, we’ll get different responses.

现在,根据请求头中发送的Accept参数的值,我们会得到不同的响应。

Let’s see this in action:

让我们看看这个行动。

curl -i \ 
-H "Accept: application/json" \ 
-H "Content-Type:application/json" \ 
-X POST --data 
  '{"username": "johnny", "password": "password"}' "https://localhost:8080/.../content"

The CURL command returns a JSON response:

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!"}

Now, let’s change the Accept parameter:

现在,让我们改变Accept参数。

curl -i \
-H "Accept: application/xml" \
-H "Content-Type:application/json" \
-X POST --data
  '{"username": "johnny", "password": "password"}' "https://localhost:8080/.../content"

As anticipated, we get an XML content this time:

正如预期的那样,这次我们得到了一个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>

4. Conclusion

4.结论

We’ve built a simple Angular client for the Spring app that demonstrates how to use the @RequestBody and @ResponseBody annotations.

我们为Spring应用建立了一个简单的Angular客户端,演示了如何使用 @RequestBody@ResponseBody注释。

Additionally, we showed how to set a content type when using @ResponseBody.

此外,我们展示了在使用@ResponseBody时如何设置内容类型。

As always, code samples are available over on GitHub.

像往常一样,代码样本可在GitHub上获得