1.简介

在本文中,会简单的介绍Spring中 @RequestBody@ResponseBody注解。

2. @RequestBody

@RequestBody注解可以将请求的主体(HttpRequest)映射到传输或模型对象,从而实现将HttpRequest主体自动反序列化到Java对象上。

我们来看一个简单的例子:

@Controller
public class RequestBodyController {
    @PostMapping("/request")
    @ResponseBody
    public String postController(
            @RequestBody LoginForm loginForm) {

        return loginForm.toString();
    }
}

根据HTTP Request Header的content-Type的内容,通过适当的HttpMessageConverter转换,Spring会自动将JSON反序列化为Java类型。

默认情况下,使用*@RequestBody*注解进行注释的类型必须与从客户端控制器发送的JSON相对应:

public class LoginForm {

    private String username;
    private String password;
  
    // get and set
}

上面的代码是将HttpRequest请求主体的对象映射到LoginForm对象。

让我们使用CURL进行测试:

# curl  -H "Content-Type:application/json" \
        -X POST --data '{"username": "test", "password": "test"}'  \
        "http://localhost:8080/request"
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 415 Unsupported Media Type</title>
</head>
<body><h2>HTTP ERROR 415 Unsupported Media Type</h2>
<table>
<tr><th>URI:</th><td>/request</td></tr>
<tr><th>STATUS:</th><td>415</td></tr>
<tr><th>MESSAGE:</th><td>Unsupported Media Type</td></tr>
<tr><th>SERVLET:</th><td>mvc</td></tr>
</table>
<hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.24.v20191120</a><hr/>

</body>
</html>

我们会发现Spring抛出了HttpMediaTypeNotSupportedException异常。

22:33:32.730 [qtp1750490055-17] DEBUG o.s.web.servlet.DispatcherServlet - POST "/request", parameters={}
22:33:32.736 [qtp1750490055-17] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to com.ripjava.spring.mvc.model.controller.RequestBodyController#postController(LoginForm)
22:33:32.752 [qtp1750490055-17] DEBUG o.s.w.s.m.m.a.ServletInvocableHandlerMethod - Could not resolve parameter [0] in public java.lang.String com.ripjava.spring.mvc.model.controller.RequestBodyController.postController(com.ripjava.spring.mvc.model.domain.LoginForm): Content type 'application/json;charset=UTF-8' not supported
22:33:32.754 [qtp1750490055-17] WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported]
22:33:32.755 [qtp1750490055-17] DEBUG o.s.web.servlet.DispatcherServlet - Completed 415 UNSUPPORTED_MEDIA_TYPE

因为@RequestBody是通过HTTP Request Header的content-Type来查找对应的HttpMessageConverter。Spring内置的处理Json的HttpMessageConverter依赖于jackson-databind。所有我们需要在pom文件中添加jackson-databind的依赖。

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.10.1</version>
</dependency>

然后我们再来测试一下:

# curl  -H "Content-Type:application/json" \
        -X POST --data '{"username": "test", "password": "test"}'  \
        "http://localhost:8080/request"
LoginForm{username='test', password='test'}%

3. @ResponseBody

@ResponseBody注解可以告诉控制器将返回的对象自动序列化为JSON并返回。

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

public class ResponseText {
    private String text;
}

然后,我们来看一个简单的例子:

@PostMapping("/request")
@ResponseBody
public String postController(
  @RequestBody LoginForm loginForm) {

  return loginForm.toString();
}

然后我们使用CURL测试一下:

# curl  -H "Content-Type:application/json" \
        -X POST --data '{"username": "test", "password": "test"}'  \
        "http://localhost:8080/response"
{"text":"test ResponseBody"}%

如果将@ResponseBody注解到控制器类上面,控制器的所有处理方法都将返回的对象自动序列化。

@Controller
@ResponseBody
public class RequestBodyController {
    @PostMapping("/request")

    public String postController(
            @RequestBody LoginForm loginForm) {

        return loginForm.toString();
    }
}

需要注意的是:在使用@RestController注释的控制器里,我们不需要使用@ResponseBody

4. 结论

在本文中,会简单的介绍Spring中 @RequestBody@ResponseBody注解。

与往常一样,可以在GitHub上获得代码示例。