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的使用姿势小结

参考技术A

SpringMVC中处理请求参数有好几种不同的方式,如我们常见的下面几种

对上面几种方式有兴趣的可以看一下这篇博文: 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重定向传参

Spring Cloud Feign 如何使用对象参数

一文搞定RequestParam注解传参,map 数组 文件(一)

Spring不同类型参数传参

@validated注解怎么用

SpringMVC 入门请求响应