@RequestBody和@ResponseBody两个注解,分别完成请求报文到对象和对象到响应报文的转换。

@RequestBody

1、@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,

比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。

作用:

  • 注解用于将Controller的方法参数,根据HTTP Request Header的content-Type的内容,通过适当的HttpMessageConverter转换为JAVA类
  • 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

说明:request的body部分的数据编码格式由header部分的Content-Type指定;

2、通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,也可以将其分别绑定到对应的字符串上。例如说以下情况:

  1.   $.ajax({
  2.         url:"/login",
  3.         type:"POST",
  4.         data:'{"userName":"admin","pwd","admin123"}',
  5.         content-type:"application/json charset=utf-8",
  6.         success:function(data){
  7.           alert("request success ! ");
  8.         }
  9.     });
  10.  
  11.     @requestMapping("/login")
  12.     public void login(@requestBody String userName,@requestBody String pwd){
  13.       System.out.println(userName+" :"+pwd);
  14.     }

这种情况是将JSON字符串中的两个变量的值分别赋予了两个字符串,但是呢假如我有一个User类,拥有如下字段:
 String userName;
 String pwd;
那么上述参数可以改为以下形式:@requestBody User user 这种形式会将JSON字符串中的值赋予user中对应的属性上
需要注意的是,JSON字符串中的key必须对应user中的属性名,否则是请求不过去的。

另外这里要注意其实 @RequestBody接收的是一个Json对象的字符串,而不是一个Json对象。

Json对象和Json字符串的区别就是有没有定义的时候有没有单引号的。。。

如果ajax请求传的是Json对象,后来用 JSON.stringify(data)的方式就能将对象变成字符串。

同时ajax请求的时候也要指定dataType: "json",contentType:"application/json" 这样就可以轻易的将一个对象或者List传到Java端,使用@RequestBody即可绑定对象或者List.。

  1. <script type="text/javascript">
  2. $(document).ready(function(){
  3. var saveDataAry=[];
  4. var data1={"userName":"test","address":"gz"};
  5. var data2={"userName":"ququ","address":"gr"};
  6. saveDataAry.push(data1);
  7. saveDataAry.push(data2);
  8. $.ajax({
  9. type:"POST",
  10. url:"user/saveUser",
  11. dataType:"json",
  12. contentType:"application/json",
  13. data:JSON.stringify(saveData),
  14. success:function(data){
  15.  
  16. }
  17. });
  18. });
  19. </script>

参考博客:json对象、json字符串的区别和相互转换

@ResponseBody

该注解用于将Controller的方法返回的对象,根据HTTP Request Header的Accept的内容,

通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。

HTTP 请求和响应是基于文本的,意味着浏览器和服务器通过交换原始文本进行通信。但是,使用 Spring,controller 类中的方法返回纯 ‘String’ 类型和域模型(或其他 Java 内建对象)。

如何将对象序列化/反序列化为原始文本?这由HttpMessageConverter 处理。

Http请求和响应报文本质上都是一串字符串,当请求报文来到java世界,它会被封装成为一个ServletInputStream的输入流,供我们读取报文。响应报文则是通过一个ServletOutputStream的输出流,来输出响应报文。

我们从流中,只能读取到原始的字符串报文,同样,我们往输出流中,也只能写原始的字符。

而在java世界中,处理业务逻辑,都是以一个个有业务意义的对象为处理维度的,那么在报文到达SpringMVC和从SpringMVC出去,都存在一个字符串到java对象的阻抗问题。

这一过程,不可能由开发者手工转换。我们知道,在Struts2中,采用了OGNL来应对这个问题,而在SpringMVC中,它是HttpMessageConverter机制。

请看:

SpringMVC源码剖析(五)-消息转换器HttpMessageConverter

HttpMessageConverter(消息转换器 )和@responsebody使用

RestTemplate中http报文转换处理

在RestTemplate中,

我们知道,调用reseful接口传递的数据内容是json格式的字符串,返回的响应也是json格式的字符串。

然而restTemplate.postForObject方法的请求参数RequestBean和返回参数ResponseBean却都是java类。是RestTemplate通过HttpMessageConverter自动帮我们做了转换的操作。

默认情况下RestTemplate自动帮我们注册了一组HttpMessageConverter用来处理一些不同的contentType的请求。

StringHttpMessageConverter来处理text/plain;MappingJackson2HttpMessageConverter来处理application/json;MappingJackson2XmlHttpMessageConverter来处理application/xml

你可以在org.springframework.http.converter包下找到所有spring帮我们实现好的转换器。

如果现有的转换器不能满足你的需求,你还可以自己实现。

请看:如何使用RestTemplate访问restful服务

注意:

StringHttpMessageConverter默认使用的字符集是ISO-8859-1,在遇到中文的时候会有乱码,所以需要移除RestTemplate默认的StringHttpMessageConverter修改字符字符集后重新设置。

spring的json转换器默认使用的是Jackson,json字符串和对应的Entity如果有字段对不上就会报错,这个有点不符合国情,而FastJson则不会报错,所以很多时候都会用FastJSON替换默认的Jackson。

配置示例:

  1. @Configuration
  2. public class RestAutoConfig {
  3.  
  4. public static class RestTemplateConfig {
  5.  
  6. @Bean//负载均衡的restTemplate
  7. @LoadBalanced //spring 对restTemplate bean进行定制,加入loadbalance拦截器进行ip:port的替换
  8. //"http://user/getusername,就能解析成http://127.0.0.1:8083//getusername
  9. RestTemplate lbRestTemplate(HttpClient httpclient) {
  10. RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpclient));
  11. template.getMessageConverters().add(,new StringHttpMessageConverter(Charset.forName("utf-8")));
  12. template.getMessageConverters().add(,new FastJsonHttpMessageConvert5());
  13. return template;
  14. }
  15.  
  16. @Bean //直连的restTemplat,这时只能使用http://127.0.0.1:8083//getusername地址,不能解析http://user/getusername
  17. RestTemplate directRestTemplate(HttpClient httpclient) {
  18. RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpclient));
  19. template.getMessageConverters().add(,new StringHttpMessageConverter(Charset.forName("utf-8")));
  20. template.getMessageConverters().add(,new FastJsonHttpMessageConvert5());
  21. return template;
  22. }
  23.  
  24. // FastJsonHttpMessageConvert4有一个bug,它是默认支持MediaType.ALL,spring在处理MediaType.ALL的时候会识别成字节流,而不是json,这里就对他进行改造和处理
  25. public static class FastJsonHttpMessageConvert5 extends FastJsonHttpMessageConverter4{
  26.  
  27. static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
  28.  
  29. public FastJsonHttpMessageConvert5(){
  30. setDefaultCharset(DEFAULT_CHARSET);
  31. setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON,new MediaType("application","*+json")));
  32. }
  33.  
  34. }
  35. }
  36.  
  37. }

HTTPclient Bean获取类:

  1. @Configuration
  2. @ConditionalOnClass({HttpClient.class})
  3. @EnableConfigurationProperties(HttpClientProperties.class)
  4. public class HttpClientAutoConfiguration {
  5.  
  6. private final HttpClientProperties properties;
  7.  
  8. public HttpClientAutoConfiguration(HttpClientProperties properties){
  9. this.properties = properties;
  10. }
  11.  
  12. /**
  13. * httpclient bean 的定义
  14. * @return
  15. */
  16. @Bean
  17. @ConditionalOnMissingBean(HttpClient.class)
  18. public HttpClient httpClient() {
  19. RequestConfig requestConfig = RequestConfig.custom()
  20. .setConnectTimeout(properties.getConnectTimeOut())
  21. .setSocketTimeout(properties.getSocketTimeOut()).build();// 构建requestConfig
  22. HttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig)
  23. .setUserAgent(properties.getAgent())
  24. .setMaxConnPerRoute(properties.getMaxConnPerRoute())
  25. .setMaxConnTotal(properties.getMaxConnTotaol())
  26. .build();
  27. return client;
  28. }
  29. }

HTTPClient参数类:

  1. @ConfigurationProperties(prefix="spring.httpclient")
  2. public class HttpClientProperties {
  3.  
  4. private Integer connectTimeOut = ;
  5.  
  6. private Integer socketTimeOut = ;
  7.  
  8. private String agent = "agent";
  9. private Integer maxConnPerRoute = ;
  10. private Integer maxConnTotaol = ;
  11. public Integer getConnectTimeOut() {
  12. return connectTimeOut;
  13. }
  14. public void setConnectTimeOut(Integer connectTimeOut) {
  15. this.connectTimeOut = connectTimeOut;
  16. }
  17. public Integer getSocketTimeOut() {
  18. return socketTimeOut;
  19. }
  20. public void setSocketTimeOut(Integer socketTimeOut) {
  21. this.socketTimeOut = socketTimeOut;
  22. }
  23. public String getAgent() {
  24. return agent;
  25. }
  26. public void setAgent(String agent) {
  27. this.agent = agent;
  28. }
  29. public Integer getMaxConnPerRoute() {
  30. return maxConnPerRoute;
  31. }
  32. public void setMaxConnPerRoute(Integer maxConnPerRoute) {
  33. this.maxConnPerRoute = maxConnPerRoute;
  34. }
  35. public Integer getMaxConnTotaol() {
  36. return maxConnTotaol;
  37. }
  38. public void setMaxConnTotaol(Integer maxConnTotaol) {
  39. this.maxConnTotaol = maxConnTotaol;
  40. }
  41.  
  42. }

@RequestBody和@ResponseBody的使用情形以及RestTemplate的http报文转换的更多相关文章

  1. springmvc实现json交互 -requestBody和responseBody

    json数据交互 1.为什么要进行json数据交互 json数据格式在接口调用中.html页面中较常用,json格式比较简单,解析还比较方便. 比如:webservice接口,传输json数据. 2. ...

  2. @RequestBody 和@ResponseBody 注解详解

    简介: @RequestBody 作用: i) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对 ...

  3. 在SpringMVC中使用@RequestBody和@ResponseBody注解处理json时,报出HTTP Status 415的解决方案

    我在使用SpringMVC的@RequestBody和@ResponseBody注解处理JSON数据的时候,总是出现415的错误,说是不支持所提交数据格式,我在页面中使用了JQuery的AJAX来发出 ...

  4. Spring MVC源码(三) ----- @RequestBody和@ResponseBody原理解析

    概述 在SpringMVC的使用时,往往会用到@RequestBody和@ResponseBody两个注解,尤其是处理ajax请求必然要使用@ResponseBody注解.这两个注解对应着Contro ...

  5. @RequestBody、@ResponseBody注解是如何将输入输出转换成json的

    @RequestBody.@ResponseBody注解,可以直接将输入解析成Json.将输出解析成Json,但HTTP 请求和响应是基于文本的,意味着浏览器和服务器通过交换原始文本进行通信,而这里其 ...

  6. @RequestParam,@RequestBody,@ResponseBody,@PathVariable注解的一点小总结

    一.前提知识: http协议规定一次请求对应一次响应,根据不同的请求方式,请求的内容会有所不同: 发送GET请求是没有请求体的,参数会直接拼接保留到url后一并发送: 而POST请求是带有请求体的,带 ...

  7. SpringMVC使用@PathVariable,@RequestBody,@ResponseBody,@RequestParam,@InitBinder

    @Pathvariable public ResponseEntity<String> ordersBack(           @PathVariable String reqKey, ...

  8. @RequestBody和@ResponseBody

    @RequestBody 将HTTP请求正文转换为适合的HttpMessageConverter对象. @ResponseBody 将内容或对象作为 HTTP 响应正文返回,并调用适合HttpMess ...

  9. SpringMVC中注解@RequestBody和@ResponseBody的使用区别

    首先上源码 在面试时经常会问到我们如何使用SpringMVC将Http请求转换为java对象,或者又是问如何将结果转换为java的呢? SpringMVC在接收到请求之后HandlerMapping像 ...

随机推荐

  1. ArrayList和Vector的区别?

    ArrayList和Vector的区别? 解答:同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程不安全的,不是同步的:数据增长:当需要增长时,Vector默认增长为原来一 ...

  2. bootstrap基础学习九篇

    现在学学bootstrap响应式实用工具 Bootstrap 提供了一些辅助类,以便更快地实现对移动设备友好的开发.这些可以通过媒体查询结合大型.小型和中型设备,实现内容对设备的显示和隐藏. 需要谨慎 ...

  3. 你 get 了无数技能,为什么一事无成

    前 几日看到阮一峰老师的发的一句话,颇有感慨,「你只是坐在电脑前,往网上发表了一段文字或者一张图片,随便什么,就能够接触到多少陌生的灵魂.这就是我热 爱互联网的原因」.我打心底认为这是一个最好的时代, ...

  4. PrintArea打印,@media screen解决移动web开发的多分辨率问题,@media print设置打印的样式

    PrintArea打印,局部DIV打印插件,依赖JQuery. github:https://github.com/RitsC/PrintArea 当打印时需要临时改变页面布局,可以使用 @media ...

  5. 用12个例子全面示范Angular的模板语法

    template分支,用12个例子全面示范Angular的模板语法 // 使用方法 git clone https://git.oschina.net/mumu-osc/learn-component ...

  6. 使用ghost硬盘对拷备份系统

    公司有台server装了OA系统.要备份数据.同一时候假设系统出错之后可以及时回复.所以有买了块同型号硬盘. 用ghost的硬盘对拷功能,将原硬盘的系统和数据拷到新硬盘上.新硬盘挂到server上.当 ...

  7. 74、shape 画圆 加 边框

    <?xml version="1.0" encoding="utf-8"?> <!--<shape xmlns:android=&quo ...

  8. Jmeter--CSV Data Set Config 参数化配置

    博客首页:http://www.cnblogs.com/fqfanqi/ 设置界面如下: Filename:参数文件名,一般是.csv和.txt文件.绝对路径和相对路径都可以,为了便于脚本迁移,建议使 ...

  9. Python2 显示 unicode

    用户想要看的是 u'中文' 而不是 u'\u4e2d\u6587',但是在 Python2 中有时并不能实现. 转译 转义字符是这样一个字符,标志着在一个字符序列中出现在它之后的后续几个字符采取一种替 ...

  10. 请写出用于校验HTML文本框中输入的内容全部为数字的javascript代码

    <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html ...