前言

前两天面试的,面试官问我用在参数上的注解有哪些?
我想了一下说有RequestParam,每个参数都需要RequestParam修饰,可以设置required 等于false,表示该字段非必传。
面试官:还有呢?
我:只知道这么多了,RequestParam 注解用的比较多,其他的没怎么用?
面试官:好了,今天的面试就到这,后续有消息会通知你。挂掉电话
我:???

结束掉面试后,好好的看了下用在参数上的注解。
用在参数上的注解,主要是controller 层,用来接收请求中的参数。
常用的有三种
@RequestParm
@RequestBody
@PathVariable

下面我们一个个看下

@RequestParam

@RequestParam 注解接收请求的参数是从request.getParameterMap()中取的。我们来先看下这个例子:

@RequestMapping(value = "/hello",method = {RequestMethod.GET,RequestMethod.POST})public String play(@RequestParam(value = "name",required = false) String name, HttpServletRequest request){Map<String, String[]> map=request.getParameterMap();for(Map.Entry<String, String[]> entry:map.entrySet()){System.out.println(entry.getKey());System.out.println(Arrays.toString(entry.getValue()));}return name+",你好!";}

@RequestMapping 表示请求的相对路径,value 是相对路径的值,method 用来限制秋衣请求的类型,我这里设置的是可以get 和post 请求。
HttpServletRequest 这个参数是方便我们得到请求的request 里面的信息。

而RequestParam 注解就是用来接收 参数name 的。
我们看下RequestParam 的源码:


@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {@AliasFor("name")String value() default "";@AliasFor("value")String name() default "";boolean required() default true;String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}

name和value 用来接收参数名,二者选其一就可以。required 默认为true 表示参数必须传,改成false 表示参数非必传。

我们现在运行看下结果


说明@RequestParam 注解是从request.parames()方法中获取到参数。

@RequestParam 可以接收post 和get 的参数。且parms 和body 中都添加的参数,会同时生效。

总结:
1、@RequestParam 注解,作用在单个参数上,并且参数不能是一个对象。因为我们看到request.getParameterMap() 接收的map 的类型为Map<String, String[]>。
2、@RequestParam 注解,多个参数可以使用多个注解,可以设置参数是否必传。
3、@RequestParam 注解获取参数是从request 中的parms 获取的。支持get 和post

@RequestBody

@RequestBody 注解是从请求体重获取参数。一个请求只有一个请求体,但是可以有多个参数,这就是为什么只能有一个@RequestBody 注解,但是可以有多个@RequestParam 注解。因为get请求没有请求体。所以@RequestBody 一般用来接收post 请求的参数,且用来接收前端传的json 字符串的。
我们还是上面的例子,稍作调整

@RequestMapping(value = "/hello1",method = {RequestMethod.GET,RequestMethod.POST})public String play1(@RequestBody String name,String sex, HttpServletRequest request){Map<String, String[]> map=request.getParameterMap();for(Map.Entry<String, String[]> entry:map.entrySet()){System.out.println(entry.getKey()+":"+Arrays.toString(entry.getValue()));}return name+",你好! \n你的性别是:"+sex;}


发现name的值是name=小明&sex=男。这说明@RequestBody 注解只能使用一个,且获取到所有的参数,我们最好不要用单一的参数接收。
我们再稍作修改。通过map 来接收请求体。

@RequestMapping(value = "/hello1",method = {RequestMethod.GET,RequestMethod.POST})public String play1(@RequestBody Map<String,Object> parms, HttpServletRequest request){Map<String, String[]> map=request.getParameterMap();for(Map.Entry<String, String[]> entry:map.entrySet()){System.out.println(entry.getKey()+":"+Arrays.toString(entry.getValue()));}return parms.get("name")+",你好! \n你的性别是:"+parms.get("sex");}


而控制台什么都没打印。

说明@RequestBody并不是从parms 中获取参数的,而是从从requestbody 中获取参数,并且是获取json 格式的参数。这时我们使用Content-Type=application/json。
如果我们使用Content-Type 等于application/x-www-form-urlencoded或者multipart/form-data 则会报错。因为不是这两者是key-value 模式的。

为什么会这样呢?因为@RequestBody 不仅能接收一个对象,还能接收一组对象。但是其他两种却不行。如下我们调整一下代码:

@RequestMapping(value = "/hello2",method = {RequestMethod.POST})public String play2(@RequestBody List<Map<String,Object>> parms){StringBuilder stringBuilder=new StringBuilder();for(Map<String,Object> map:parms){stringBuilder.append(map.get("name")+",你好! \n你的性别是:"+map.get("sex")+"\n");}return stringBuilder.toString();}


可以看到@RequestBody 还是有自己的优势的,不仅如此,RequestBody不但可以接收map,还可以接收我们自定义的bean。如下:我们先创建一个user 实体

public class User {private String name;private String sex;private int age;//getter和setter 方法
}

然后写一个接口

@RequestMapping(value = "/hello3",method = {RequestMethod.GET,RequestMethod.POST})public String play3(@RequestBody List<User> users){StringBuilder stringBuilder=new StringBuilder();for(User user:users){stringBuilder.append(user.getName()+",你好! \n你的性别是:"+user.getSex()+"\n");}return stringBuilder.toString();}


看到可以达到一样的效果,还省去了我们转换。

总结:
1、@RequestBody 注解 接收请求体中参数,接收post请求,不能接收get 请求。且只能有一个RequestBody 注解。
2、@RequestBody 注解多用来接收json 传参。可以是map,对象,list.

@PathVariable

@PathVariable 注解是接收请求路径中的占位符的值。如下:

@RequestMapping(value = "/hello4/{name}/{sex}",method = {RequestMethod.GET,RequestMethod.POST})public String play4(@PathVariable String name,@PathVariable String sex) {return name+",你好! \n你的性别是:"+sex;}


其他的作用和RequestParam 是一样的。他只能接收单个参数,url 中有几个占位符,就有几个@Pathvariable 注解。

无注解接收参数

还有一种情况,放在最后,我们在接口的时候请求参数没有任何注解,也可以接收到请求的参数。看下面去掉@RequestParam 注解

 @RequestMapping(value = "/hello5",method = {RequestMethod.GET,RequestMethod.POST})public String play5(String name,String sex, HttpServletRequest request){Map<String, String[]> map=request.getParameterMap();for(Map.Entry<String, String[]> entry:map.entrySet()){System.out.println(entry.getKey()+":"+Arrays.toString(entry.getValue()));}return name+",你好! \n你的性别是:"+sex;}



并且还支持参数非必传。

我们再试试不用@RequestBody 注解

@RequestMapping(value = "/hello6",method = {RequestMethod.GET,RequestMethod.POST})public String play6( User user){return user.getName()+",你好! \n你的性别是:"+user.getSex();}


发现并没有获取到值。
造成上述的原因:其实是默认是使用@RequestParam 注解,且 ruquires=false。所以当我们使用注解的时候,单个的参数也可以直接获取到。

后记

总算差不多了,现在面试官有本事再问我这个问题试试,看我不怼回去。

兄弟们,写作不易,觉得可以的点个赞和收藏哈哈。

面试不是无情物,参数注解知多少?相关推荐

  1. 数仓面试|四个在工作后才知道的SQL密技

    SQL是大数据从业者的必备技能,大部分的大数据技术框架也都提供了SQL的解决方案.可以说SQL是一种经久不衰.历久弥新的编程语言.尤其是在数仓领域,使用SQL更是家常便饭.本文会分享四个在面试和工作中 ...

  2. java 获取自定义参数类型_Springboot中使用自定义参数注解获取 token 中用户数据...

    使用自定义参数注解获取 token 中User数据 使用背景 在springboot项目开发中需要从token中获取用户信息时通常的方式要经历几个步骤 拦截器中截获token TokenUtil工具类 ...

  3. R语言使用caret包构建GBM模型:在模型最优参数已知的情况下,拟合整个训练集,而无需进行任何重采样或参数调优

    R语言使用caret包构建GBM模型:在模型最优参数已知的情况下,拟合整个训练集,而无需进行任何重采样或参数调优 目录 R语言使用caret包构建GBM模型:在模型最优参数已知的情况下,拟合整个训练集 ...

  4. python语言的变量随时_Python参数注解

    #### 1.函数定义的弊端 - python是动态语言,变量随时可以被赋值,且能赋值为不同的类型,动态语言很灵活,但是这种特性也是弊端: - **难发现**:由于不做任何类型检查,直到运行期问题才显 ...

  5. java自定义方法参数注解_Java方法中的参数太多,第1部分:自定义类型

    java自定义方法参数注解 我认为构造函数和方法中冗长的参数列表是Java开发中的另一个" 危险信号 ",就逻辑和功能而言,它们不一定是"错误的",但通常暗示当 ...

  6. python参数注解

    函数定义的弊端: python是动态语言,变量随时可以被赋值,且能赋值为不同的类型,动态语言很灵活,但是这种特性也是弊端 难发现:由于不做任何类型检查,直到运行期问题才显现出来,或者线上运行时才能暴露 ...

  7. x264(一)-x264参数注解:x264_param_t

     x264参数注解:x264_param_t typedef struct x264_param_t { // CPU 标志位 */ unsigned int cpu; int         i ...

  8. 面试:SpringBoot中的条件注解底层是如何实现的?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源 | https://urlify.cn/bm2qqi Spr ...

  9. Swagger使用————接口参数注解的使用缺陷

    问题描述 在使用springboot开发web项目时,用到了swagger框架,来生成web api文档.但是其中有一项是举例说明参数的结构,如下图: 但是,这个功能真的是非常方便,因为可以让前端开发 ...

最新文章

  1. 重磅直播|光学3D测量技术原理及应用
  2. Spring中应用反射机制浅析
  3. mageia linux 5.1 内核,Linux 5.10 LTS发布 为近期最重要的内核版本之一
  4. curl 下载 dropbox
  5. 【最爽的日期工具包LocalDate·超爽,超实用】(Java8版本)
  6. (pytorch-深度学习系列)pytorch中backwards()函数对梯度的操作
  7. JAVA基础面试题,java高级面试笔试题
  8. aws python sns_使用AWS Lambd从AWS SNS读取时修改JSON消息
  9. 嗅探TFTP配置文件传输
  10. 做品牌 在男人和女人之间玩转巧妙和平衡
  11. wxWindows入门
  12. MP3、MP4、MP5、PSP
  13. 工行u盾显示316_工行网银客户端检测不到U盾的解决方法
  14. 华为2019届校招笔试题及解法
  15. 程序员真的很孤独吗?
  16. cdrom是什么意思_开启电脑时出现CDROM是什么意思
  17. 【机器学习】课程设计布置:某闯关类手游用户流失预测
  18. STC8PMW波输出
  19. AG256SL100 与EPM240T100 完全PIN TO PIN兼容
  20. 字符串转为日期,日期转为字符串

热门文章

  1. JavaScript脑图
  2. 应届毕业生,让人欢喜让人忧
  3. 【MarkDown使用技巧】轻松搞定MarkDown
  4. Linux 安装redis5.0.7 设置密码,开启远程访问
  5. 高斯判别分析(GDA)
  6. 内积与外积(Inner/Outer/Interior/Exterior)Product 及在计算机中的概念
  7. 中国超2亿人单身,一线城市单身青年4成月光
  8. 拟募资超10亿元,索辰科技能否成为科创板CAE软件第一股?
  9. PHP开发很好用的编辑器,
  10. SQL轻松入门(1):增删改与简单查询