RequestBody和ResponseBody解读
前言:@RequestBody和@ResponseBody是SpringMVC的两个注解,用于将请求体的内容转换为指定对象 和 将返回对象直接写入响应body中
正常SpringMVC工作流程
正常工作流程大家应该都很清楚,Servlet容器接收http请求,将请求交给前端控制器,前端控制器根据请求路径查询到相应的Controller,调用该Controller,处理完数据后返回模型数据,再经视图解析器解析转发到相应的视图进行处理,最后才返回响应消息给客户端。
HTTP信息转换器
HTTP信息转换器是SpringMVC提供的一个很有用的工具,用于构建RESTful API(表述性状态转移),即客户端传入数据,经过SpringMVC处理后直接返回数据,不再需要转发到视图进行渲染。与标准流程相比,这里少了模型和视图解析的步骤。
这里介绍最常用的两种格式相关的信息转换器
- Jaxb2RootElementHttpMessageConverter
在xml(contentType包括text/xml和application/xml)和使用JAXB2注解的对象之间相互读取和写入
注册条件: JAXB v2库在类路径下时将进行注册 - MappingJacksonHttpMessageConverter
在JSON和类型化的对象或非类型化的HashMap之间读取和写入
注册条件:jackson JSON库在类路径下时将进行注册 - MappingJackson2HttpMessageConverter
在JSON和类型化的对象或非类型化的HashMap之间读取和写入
注册条件:jackson 2 JSON库在类路径下时将进行注册
在响应体中返回状态资源
如果启用消息转换功能,我们需要告诉Spring跳过正常的流程,并且使用消息转换器。如下的代码段,将直接在响应体中添加json数据
@RequestMapping("/uploadImage.do")
@ResponseBody
public Map<String, String> receiveImage() {
Map<String, String> map = new HashMap<String, String>();
map.put("arg0", "1");
map.put("arg1", "2");
return map;
}
["arg0":"1", "arg2":"2"]
具体地将,DispatcherServlet将会考虑到请求中头部的Accept字段的信息,查找能够为客户端提供所需表述形式的消息转换器(当然有时也不是这样)
这里,假设客户端的accept为”application/json”,且jackson库就在类路径下,则会调用MappingJacksonHttpMessageConverter将返回的map转换为json数据。
注: 实测了一下,accept为*/*时,只要jackson库在类路径下,且返回的是map,也会默认转换为json数据。
直接返回xml的情况稍微复杂一点,需要满足三个条件
- accept为text/xml或application/xml
- JAXB库在类路径下
- 返回对象的类必须是被jaxb注解修饰过的
这里不进行举例,可以参考别的博文:https://blog.youkuaiyun.com/chenpeng19910926/article/details/53155891
在请求体中接收资源状态
使用@RequestBody可以直接将请求体中的内容转换为我们想要的对象,具体来讲:
- 如果请求头的contentType为application/json,且jackson库在类路径下,则会按照JSON的方式将数据填充到我们的对象中
- 如果contentType为application/xml或text/xml,且jaxb在类路径下,则会调用xml的消息转换器进行转换。
为控制器设置默认消息转换
当我们整个类中全部都使用消息转换时,为每一个方法添加ResponseBody和RequestBody注解显得重复,可以使用@RestController注解替代@Controller注解,表示该类中的所有方法默认都开启消息转换。