spring MVC中接口参数解析的过程详解

 更新时间:2018年07月06日 09:24:16   作者:007tangtao  
这篇文章主要给大家介绍了关于spring MVC中接口参数解析的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用spring mvc具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

前天工作中遇到了这样一个问题,我在接口的参数封装了一个pojo,这是很常见的,当参数一多,惯性的思维就是封装一个pojo.那么在参数前有很多注解可以添加,比如:@requestParam,@requestBody,@pathvariable等。我的理解是这样的,首先我先申明,我并是没有看过源码,只是凭经验理解。@requestParam试用于get请求,参数在http的header中的URL上,具体放在?后面以key=value的形式存在。@requestBody适用于post请求中参数在http的body中。@pathvariable比较特别是restful的写法,把参数放在URL上,不用问号区分是参数还是URL。也许我这样说不是很准确。但我通常也是这么用的。与此同时,还有一种常见的写法,就是参数前不加注解,比如参数是基本类型的不加@requestParam,参数是bean的不加requestBody,也能被springmvc解析得到。我的接口被小组长看到之后他叫我去掉这个@requestBody,因为后端加上这个之后,前端的ajax请求需要显示的声明content-type:"application/json",才能被springmvc解析得到,这样似乎多做了一件不必要的事情。虽然我按照他的要求去掉了,但是我觉得我得弄清楚这到底是怎么回事,加与不加到底有什么区别,对性能有什么影响,或者各自的最佳适用场景,除了百度,还得问问大神。

spring MVC接口参数解析的过程

首先我自己慢慢的通过debug研究了一下源码。在不添加任何注解的情况下:

在开发的过程中consumes和produces一般都没有加,按道理应该要加上,因为可以减少对接口的查找范围。这是一个简单的demo,我只是需要他来检查springmvc接收请求的流程。

首先在tomcat启动之后,所有controller类中的请求路径也就是@requestMapping随着Controller这个bean加载到了spring的容器中。页面请求过来之后找到DispatcherServlet这个servlet,请求走到servlet之后大家都知道servlet有两种初始化方式,一种是随着立即加载,一种是延迟加载,但是无论怎样,都是只调用一次init方法,然后再以后每次都会直接调用service方法,当tomcat关闭之后servlet的destroy方法被调用生命周期就结束了。所以springmvc是对servlet的封装就必定要继承service方法,DispatcherServlet也就是doDispatch这个方法。这个方法中通过HttpServletRequest对象获得请求路径也就是/notJson,然后与容器中的所有url对比,最终取得Controller中的接口所在。找到了接口自然就知道了接口的参数,我这里就是Display,为了方便简单,Display中只有两个参数,就是下面ajax请求中的两个。

springmvc会通过反射的方式获取到pojo中的属性。在这个过程中首先springmvc会先声明一个数组,这个数组的大小是参数的个数,我这里只有一个,其实我相信很多人会和我遇到相同的问题就是,当参数中同时存在bean和基本类型的参数,springmvc将怎么解析,这个我遇到过几次,在没有看源码的情况下,把基本类型也封装到bean中去了,让前端把属性也写在一个对象中。当然我相信这个不是每个人都能接受的做法,我们都希望搞清楚他究竟是怎样解析的,到时候我们就可以任意摆弄了。下面是反射过程,将我的pojo反射之后获得里面的属性和方法。解析了参数之后,为参数赋值。这里也许是最重要的地方了。究竟是怎么赋值的。

从这个方法debug了解到,name为display,也就是pojo类名的小写,这里不知道为什么springmvc做了这个处理(以后再看)。attribute为带有age和name的对象。不过此时都是null。WebDataBinding用于从Web请求参数到JavaBean对象的数据绑定的特殊DataBinder。接上图bindRequestParameters这个方法,跟进去会发现一个很熟悉的地方就是下图,通过String[] values = request.getParameterValues(paramName);获得参数名,这个是servlet的获取参数方法,那么就可以知道请求的参数的属性名和属性值。

接下来可想而知就是把这个参数名name换成bean的属性name,参数名age换成属性名age。再跟到这个地方,这个oragina就是上面serclet拿到的属性名值对,把这个map在这转化成PropertyValue。(PropertyValue是用于保存单个bean属性的信息和值的对象。 在此处使用对象,而不是仅将所有属性存储在由属性名称键入的映射中,允许更灵活,并且能够以优化的方式处理索引属性等。请注意,该值不需要是最终所需的类型:BeanWrapper实现应该处理任何必要的转换,因为此对象不知道它将应用于哪些对象。),如此一来就有两个PropertyValue对象了。

转化的时候会忽略不知道的属性

上图是具体转化的方法,方法比较长。下面一句直接给bean赋值。从这个过程来看。只要前端的json对象的属性和后端的bean属性一样,ajax不写content-type,用默认的application/x-www-form-urlencoded; charset=UTF-8,就能直接赋值。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • Spring Boot中利用JavaMailSender发送邮件的方法示例(附源码)

    Spring Boot中利用JavaMailSender发送邮件的方法示例(附源码)

    这篇文章主要介绍了Spring Boot中利用JavaMailSender发送邮件的方法示例, 相信使用过Spring的众多开发者都知道Spring提供了非常好用的JavaMailSender接口实现邮件发送。在Spring Boot的Starter模块中也为此提供了自动化配置。需要的朋友可以参考借鉴。
    2017-02-02
  • java线程池详解及代码介绍

    java线程池详解及代码介绍

    这篇文章主要介绍了java中线程池的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • Idea如何关闭或开启引用提示Usages和Annotations

    Idea如何关闭或开启引用提示Usages和Annotations

    这篇文章主要介绍了Idea如何关闭或开启引用提示Usages和Annotations问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • SpringBoot配置类编写过程图解

    SpringBoot配置类编写过程图解

    这篇文章主要介绍了SpringBoot配置类编写过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java设计模式之外观模式

    Java设计模式之外观模式

    这篇文章介绍了Java设计模式之外观模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • IntelliJ IDEA使用教程从入门到上瘾(2019图文版)

    IntelliJ IDEA使用教程从入门到上瘾(2019图文版)

    这篇文章主要介绍了IntelliJ IDEA使用教程从入门到上瘾(2019图文版),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • Java 对 Properties 文件的操作详解及简单实例

    Java 对 Properties 文件的操作详解及简单实例

    这篇文章主要介绍了Java 对 Properties 文件的操作详解及简单实例的相关资料,需要的朋友可以参考下
    2017-02-02
  • SpringBoot+MinIO实现对象存储方式

    SpringBoot+MinIO实现对象存储方式

    这篇文章主要介绍了SpringBoot+MinIO实现对象存储方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • 解决IDEA的Terminal中文乱码问题

    解决IDEA的Terminal中文乱码问题

    这篇文章主要介绍了解决IDEA的Terminal中文乱码问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • java中的除法运算和取模运算解读

    java中的除法运算和取模运算解读

    这篇文章主要介绍了java中的除法运算和取模运算,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08

最新评论