博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringMVC @RequestBody的使用
阅读量:5139 次
发布时间:2019-06-13

本文共 5396 字,大约阅读时间需要 17 分钟。

 

@RequestBody的作用

@RequestBody用于读取Request请求的body数据,然后利用SpringMVC配置的HttpMessageConverter对数据进行转换,最后把转换后的数据绑定到被@RequestBody注解的参数上;

@RequestBody的使用场景

根据request header中 Content-Type和被@RequestBody注解的参数不同,最常见的应用场景如下:

  1.  Content-Type为application/json
    • 参数为JavaBean:可实现json反序列化为JavaBean,使用的HttpMessageConverter为 MappingJackson2HttpMessageConverter
    • 参数为String:简单将字符串赋值给参数,使用的HttpMessageConverter为 StringHttpMessageConverter
  2.  Content-Type为application/xml
    • 参数为JavaBean可实现xml反序列化为JavaBean,使用的HttpMessageConverter为 Jaxb2RootElementHttpMessageConverter
    • 参数为String:简单将字符串赋值给参数,使用的HttpMessageConverter为 StringHttpMessageConverter
  3. application/x-www-form-urlencoded
    • 参数为String:简单将字符串赋值给参数,使用的HttpMessageConverter为 StringHttpMessageConverter

HttpMessageConverter接口

该接口定义了五个方法,分别是读取数据时的 canRead()、read() ,写入数据时的canWrite()、 write()方法以及获取支持类型的 getSupportedMediaTypes()

public interface HttpMessageConverter
{// Indicate whether the given class and media type can be read by this converter.boolean canRead(Class
clazz, MediaType mediaType);// Indicate whether the given class and media type can be written by this converter.boolean canWrite(Class
clazz, MediaType mediaType);// Return the list of MediaType objects supported by this converter.List
getSupportedMediaTypes();// Read an object of the given type from the given input message, and returns it.T read(Class
clazz, HttpInputMessage inputMessage) throws IOException,HttpMessageNotReadableException;// Write an given object to the given output message.void write(T t, HttpOutputMessage outputMessage) throws IOException,HttpMessageNotWritableException;}

使用 <mvc:annotation-driven />标签配置时,默认配置了RequestMappingHandlerAdapter,并为他配置了一下默认的HttpMessageConverter:

  1. ByteArrayHttpMessageConverter: 负责读取二进制格式的数据和写出二进制格式的数据;
  2. StringHttpMessageConverter:   负责读取字符串格式的数据和写出二进制格式的数据;
  3. ResourceHttpMessageConverter:负责读取资源文件和写出资源文件数据; 
  4. FormHttpMessageConverter:       负责读取form提交的数据(能读取的数据格式为 application/x-www-form-urlencoded,不能读取multipart/form-data格式数据);负责写入application/x-www-from-urlencoded和multipart/form-data格式的数据;
  5. MappingJacksonHttpMessageConverter:  负责读取和写入json格式的数据;
  6. SouceHttpMessageConverter:                   负责读取和写入 xml 中javax.xml.transform.Source定义的数据;
  7. Jaxb2RootElementHttpMessageConverter:  负责读取和写入xml 标签格式的数据;
  8. AtomFeedHttpMessageConverter:              负责读取和写入Atom格式的数据;
  9. RssChannelHttpMessageConverter:           负责读取和写入RSS格式的数据;

 

HttpMessageConverter匹配过程

根据Request对象header部分的ContentType类型和被注解参数类型,逐一匹配合适的HttpMessageConverter来读取数据;

protected 
Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {...... MediaType contentType; contentType = inputMessage.getHeaders().getContentType();....... for (HttpMessageConverter
converter : this.messageConverters) { Class
> converterType = (Class
>) converter.getClass(); if (converter instanceof GenericHttpMessageConverter) { GenericHttpMessageConverter
genericConverter = (GenericHttpMessageConverter
) converter; if (genericConverter.canRead(targetType, contextClass, contentType)) { if (logger.isDebugEnabled()) { logger.debug("Read [" + targetType + "] as \"" + contentType + "\" with [" + converter + "]"); } if (inputMessage.getBody() != null) { inputMessage = getAdvice().beforeBodyRead(inputMessage, parameter, targetType, converterType); body = genericConverter.read(targetType, contextClass, inputMessage); body = getAdvice().afterBodyRead(body, inputMessage, parameter, targetType, converterType); } else { body = getAdvice().handleEmptyBody(null, inputMessage, parameter, targetType, converterType); } break; } } else if (targetClass != null) { if (converter.canRead(targetClass, contentType)) { if (logger.isDebugEnabled()) { logger.debug("Read [" + targetType + "] as \"" + contentType + "\" with [" + converter + "]"); } if (inputMessage.getBody() != null) { inputMessage = getAdvice().beforeBodyRead(inputMessage, parameter, targetType, converterType); body = ((HttpMessageConverter
) converter).read(targetClass, inputMessage); body = getAdvice().afterBodyRead(body, inputMessage, parameter, targetType, converterType); } else { body = getAdvice().handleEmptyBody(null, inputMessage, parameter, targetType, converterType); } break; } } }....... return body; }

 

注意

  1. 在一个方法的参数列表中,@RequestBody只能使用一次;
  2. json字符串中,如果value为""的话,后端对应属性如果是String类型的,那么接受到的就是"",如果是后端属性的类型是Integer、Double等类型,那么接收到的就是null;
  3. json字符串中,如果value为null的话,后端对应收到的就是null;
  4. 在传json字符串给后端时,如果某个key没有value的话,要么干脆就不写该key,要么就将value赋值null  或"",不能有类似 {......,"key":,.....}, 这样的写法

转载于:https://www.cnblogs.com/canger/p/10333132.html

你可能感兴趣的文章
16 合并两个排序的链表Merge two sorted linkedlist<TODO输入两个链表>
查看>>
Qt5学习笔记 | 给窗口添加动作
查看>>
Html Table to Excel 的一种实现 (PHP)
查看>>
将MSSQL2005的用户数据库导入到godaddy
查看>>
Fluent NHibernate Component
查看>>
poj 1190 DFS 不等式放缩进行剪枝
查看>>
我所理解的RESTful Web API [Web标准篇]
查看>>
RabbitMQ与.net core(一)安装
查看>>
WPF自定义控件(五)の用户控件(完结)
查看>>
[UWP小白日记-15]在UWP手机端实时限制Textbox的输入
查看>>
SQL挑战——如何高效生成编码
查看>>
MVC5+EF6 入门完整教程13 -- 动态生成多级菜单
查看>>
Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅
查看>>
.Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
查看>>
MVC把随机产生的字符串转换为图片
查看>>
Tomcat通过JNDI方式链接MySql数据库
查看>>
SQLSERVER如何获取一个数据库中的所有表的名称、一个表中所有字段的名称
查看>>
性能测试小总结(一) 基础概念
查看>>
hash-6.CopyOnWriteArrayList
查看>>
对商品浏览记录的理解
查看>>