Spring传参数注解技术
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring传参数注解技术相关的知识,希望对你有一定的参考价值。
参考技术A 一、mybatis传多个参数(不使用@param注解情况和使用@param注解的情况)转自 https://blog.csdn.net/qq_39505065/article/details/90550705
方法1:顺序传参法
1.不使用@param注解传递多个参数的情况
注: 使用jdk1.7得到的是: [1, 0, param1, param2]
使用1.8得到的则是: [arg1, arg0, param1, param2]
这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。
举个栗子:
Dao层
List<User> demo(int userid, String name);
对应的XML编写
jdk1.7
<select id="demo" resultMap="User">
select *
from user where user_id=#0 and name= #1
</select>
jdk1.8之后
第一种写法
<select id="demo" resultMap="User">
select *
from user where user_id=#arg0 and name= #arg1
</select>
第二种写法
<select id="demo" resultMap="User">
select *
from user where user_id=#param0 and name= #param1
</select>
方法2:@Param注解传参法
public User selectUser(@Param("userName") String name, int @Param("deptId") deptId);
<select id="selectUser" resultMap="UserResultMap">
select * from user
where user_name = #userName and dept_id = #deptId
</select>
这种方法在参数不多的情况还是比较直观的,推荐使用。
方法3:Map传参法
public User selectUser(Map<String, Object> params);
<select id="selectUser" parameterType="java.util.Map" resultMap="UserResultMap">
select * from user
where user_name = #userName and dept_id = #deptId
</select>
这种方法适合传递多个参数,且参数易变能灵活传递的情况。
方法4:Java Bean传参法
public User selectUser(Map<String, Object> params);
<select id="selectUser" parameterType="com.test.User" resultMap="UserResultMap">
select * from user
where user_name = #userName and dept_id = #deptId
</select>
这种方法很直观,但需要建一个实体类,扩展不容易,需要加属性,看情况使用。
二、《Spring @RequestParam注解的使用》
https://blog.csdn.net/Third_Week/article/details/90376578
重磅来袭:Spring之RequestBody的使用姿势小结
参考技术ASpringMVC中处理请求参数有好几种不同的方式,如我们常见的下面几种
对上面几种方式有兴趣的可以看一下这篇博文: SpringMVC之请求参数的获取方式
除了上面的几种方式之外,还有一种 @RequestBody 的使用方式,本文则主要介绍这种传参的使用姿势和相关注意事项
借助Spring框架,使用@RequestBody并没有什么难度,很简单的就可以写一个使用case出来,如下
看上面的实现,和我们通常的写法并无差别,无非是将以前的 @RequsetParam 注解换成 @RequsetBody 注解,而且这个注解内部只有一个filed,比RequsetParam还少
看到上面的实现,估计也可以猜出,这个注解对于后端而言,写没啥问题,关键是如何用(具体来讲是如何给前端用)
上面写完了,接下来的重点就是如何使用了,在使用之前,有必要了解下 RequestBody 这个注解出现的原有以及应用场景(换句话说它和RequestParam有什么区别,为什么要单独地搞一个这个东西出来)
RequestBody
a. content-type定义
在进入下一步之前,有必要说一下Content-Type这个http请求头的作用了,下面一段来自其他博文,原文链接见最后
常见媒体格式如下:
以application开头的媒体格式类型:
b. content-type 实例说明
上面算是基本定义和取值,下面结合实例对典型的几种方式进行说明
对于前端使用而言,form表单的enctype属性为编码方式,常用有两种:
application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded。
Get请求
发起Get请求时,浏览器用
application/x-www-form-urlencoded方式,将表单数据转换成一个字符串(key1=value1&key2=value2...)拼接到url上,这就是我们常见的url带请求参数的情况
Post表单
发起post请求时,如果没有传文件,浏览器也是将form表单的数据封装成k=v的结果丢到http body中,拿开源中国的博客提交的表单为例,一个典型的post表单,上传的数据拼装在form data中,为kv结构
如果有传文件的场景,Content-Type类型会升级为multipart/form-data,这一块不详细展开,后面有机会再说
Post json串
post表单除了前面一种方式之外,还有一种也是我们常见的,就是将所有的表单数据放在一个大的json串中,然后丢给后端,这里也有一个在线的实例,某电商平台的商品发表,截图如下
注意看上面的Request Payload,是一个大的json串,和前面差别明显
c. RequestBody请求
根据RequestBody的定义,要想访问前面定义的那个接口,使用传统的表单传递方式是不行的,curl命令测试如下
后端对应的输出如下(抛了一个异常,表示@RequestBody注解修饰rest接口,不支持 Content type \'
application/x-www-form-urlencoded;charset=UTF-8\'
因此使用姿势需要显示添加请求头,传参也改变一下
返回结果如下
a. content-type显示指定
根据前面的说明,可以知道 @RequestBody 这个注解的使用,使得REST接口接收的不再content-type为
application/x-www-form-urlencoded的请求, 反而需要显示指定为application/json
b. 请求方法
RequestBody支持GET方法么?前面都是采用post提交参数,如果改成GET会怎样?
curl测试方式
对应的后端debug截图如下,发现使用GET方式,并没有问题,依然可以获取到参数
换成大名鼎鼎的POSTMAN来测试
使用post方法请求时,截图如下,主要就是修改header的content-type,然后在body中添加json串格式的请求
然而改成get之后,body都直接灰掉了,也就是它不支持在get请求时,提交Body数据
url请求方式
接下来直接换成url的请求方式,看是否直接支持get请求
浏览器中输入时,服务器400, 换成curl方式请求,抛的是缺少RequestBody的异常,也就是说,将json串拼接到url中貌似不行(也有可能是我的使用姿势不对。。。)
小结
c. 参数获取
这个主要就是后端编写接口时,获取RequestBody参数的问题了,通过测试,发现在HttpServletRequest参数中,居然拿不到提交的RequestBody参数,演示如下
请求url为
对应的debug截图如下,url参数可以拿到,RequestBody参数没有
首先声明,下面的这段分析,没有看源码,纯属于个人推断,如有问题,对被误导的朋友表示歉意,也希望对此有了解的朋友,多多批评指正
对上面的猜测做一个小小的验证,改成直接从HttpServletRequest的Reader流中获取请求body参数
验证如下
其实到这里,有个有意思的地方已经引起了我的好奇,那就是在Spring容器中HttpServletRequest这个东西,是怎么运转的,后面有机会再聊,此处不展开...
</article>
最后,我还整理了一份面试宝典,有需要的私信小助理【666】
以上是关于Spring传参数注解技术的主要内容,如果未能解决你的问题,请参考以下文章
ModelAttribute注解使用与spring重定向传参