@RequestParam详解

@RequestParam

主要用于将请求参数区域的数据映射到控制层方法的参数上
在这里插入图片描述

首先我们需要知道@RequestParam注解主要有哪些参数

  1. value:请求中传入参数的名称,如果不设置后台接口的value值,则会默认为该变量名。比如上图中第一个参数如果不设置value=“page”,则前端传入的参数名必须为pageNum,否则在后台接口中pageNum将接收不到对应的数据

  2. required:该参数是否为必传项。默认是true,表示请求中一定要传入对应的参数,否则会报404错误,如果设置为false时,当请求中没有此参数,将会默认为null,而对于基本数据类型的变量,则必须有值,这时会抛出空指针异常。如果允许空值,则接口中变量需要使用包装类来声明。

  3. defaultValue:参数的默认值,如果请求中没有同名的参数时,该变量默认为此值。注意默认值可以使用SpEL表达式,如"#{systemProperties[‘java.vm.version’]}"

如果在请求中传入多个同名参数,比如:url?userName=zhl&userName=holley时怎么办?

其实此时传入的数据格式是:“zhl,holley”,即多个数据之间使用逗号分隔开,在后台接口中可以使用数组或者list类型的变量来接收:

public String requestparam8(@RequestParam(value="userName") String []  userNames) 
或者
public String requestparam8(@RequestParam(value="list") List<String> list) 

@PathVariable绑定uri模板变量值:通过@PathVariable可以绑定占位符参数到方法参数中,例如:

在这里插入图片描述
如果请求为"url/info/16",则spring会自动将16绑定到通过@PathVariable注解的同名变量uid上

@CookieValue绑定Cookie数据值

@CookieValue用于将请求的Cookie数据映射到功能处理方法的参数上。

public String test(@CookieValue(value="JSESSIONID", defaultValue="") String sessionId) 

如上配置将自动将JSESSIONID值入参到sessionId参数上,defaultValue表示Cookie中没有JSESSIONID时默认为空。

public String test2(@CookieValue(value="JSESSIONID", defaultValue="") Cookie sessionId)   

传入参数类型也可以是javax.servlet.http.Cookie类型

测试代码在CookieValueTypeController中。@CookieValue也拥有和@RequestParam相同的三个参数,含义一样。

@RequestHeader绑定请求头数据

@RequestHeader用于将请求的头信息区数据映射到功能处理方法的参数上。

@RequestMapping(value="/header")  
public String test(  @RequestHeader("User-Agent") String userAgent,  @RequestHeader(value="Accept") String[] accepts)

如上配置将自动将请求头“User-Agent”值入参到userAgent参数上,并将“Accept”请求头值入参到accepts参数上。测试代码在HeaderValueTypeController中。

@RequestHeader也拥有和@RequestParam相同的三个参数,含义一样。

@ModelAttribute绑定请求参数到命令对象

@ModelAttribute一个具有如下三个作用:

①绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定流程,而且自动暴露为模型数据用于视图页面展示时使用;

②暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping注解的方法)之前,自动添加到模型对象中,用于视图页面展示时使用;

③暴露@RequestMapping方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。

一、绑定请求参数到命令对象

如用户登录,我们需要捕获用户登录的请求参数(用户名、密码)并封装为用户对象,此时我们可以使用@ModelAttribute绑定多个请求参数到我们的命令对象。

public String test1(@ModelAttribute("user") UserModel user) 

它的作用是将该绑定的命令对象以“user”为名称添加到模型对象中供视图页面展示使用。我们此时可以在视图页面使用${user.username}来获取绑定的命令对象的属性。

绑定请求参数到命令对象支持对象图导航式的绑定,如请求参数包含“?username=zhang&password=123&workInfo.city=bj”自动绑定到user中的workInfo属性的city属性中。

@RequestMapping(value="/model2/{username}")  
public String test2(@ModelAttribute("model") DataBinderTestModel model) {   

DataBinderTestModel相关模型请从第三章拷贝过来,请求参数到命令对象的绑定规则详见【4.16.1、数据绑定】一节,URI模板变量也能自动绑定到命令对象中,当你请求的URL中包含“bool=yes&schooInfo.specialty=computer&hobbyList[0]=program&hobbyList[1]=music&map[key1]=value1&map[key2]=value2&state=blocked”会自动绑定到命令对象上。

当URI模板变量和请求参数同名时,URI模板变量具有高优先权。

二、暴露表单引用对象为模型数据

@ModelAttribute("cityList")  
public List<String> cityList() {  return Arrays.asList("北京", "山东");  
} 

如上代码会在执行功能处理方法之前执行,并将其自动添加到模型对象中,在功能处理方法中调用Model 入参的containsAttribute(“cityList”)将会返回true。

@ModelAttribute("user")  //①  
public UserModel getUser(@RequestParam(value="username", defaultValue="") String username) {  
//TODO 去数据库根据用户名查找用户对象  
UserModel user = new UserModel();  
user.setRealname("zhang");  return user;  
}

如你要修改用户资料时一般需要根据用户的编号/用户名查找用户来进行编辑,此时可以通过如上代码查找要编辑的用户。

也可以进行一些默认值的处理。

@RequestMapping(value="/model1") //②  
public String test1(@ModelAttribute("user") UserModel user, Model model)  

此处我们看到①和②有同名的命令对象,那Spring Web MVC内部如何处理的呢:

(1、首先执行@ModelAttribute注解的方法,准备视图展示时所需要的模型数据;@ModelAttribute注解方法形式参数规则和@RequestMapping规则一样,如可以有@RequestParam等;

(2、执行@RequestMapping注解方法,进行模型绑定时首先查找模型数据中是否含有同名对象,如果有直接使用,如果没有通过反射创建一个,因此②处的user将使用①处返回的命令对象。即②处的user等于①处的user。

三、暴露@RequestMapping方法返回值为模型数据

public @ModelAttribute("user2") UserModel test3(@ModelAttribute("user2") UserModel user) 

大家可以看到返回值类型是命令对象类型,而且通过@ModelAttribute(“user2”)注解,此时会暴露返回值到模型数据(名字为user2)中供视图展示使用。那哪个视图应该展示呢?此时Spring Web MVC会根据RequestToViewNameTranslator进行逻辑视图名的翻译.

此时又有问题了,@RequestMapping注解方法的入参user暴露到模型数据中的名字也是user2,其实我们能猜到:

(3、@ModelAttribute注解的返回值会覆盖@RequestMapping注解方法中的@ModelAttribute注解的同名命令对象。

四、匿名绑定命令参数

public String test4(@ModelAttribute UserModel user, Model model)public String test5(UserModel user, Model model)   

此时我们没有为命令对象提供暴露到模型数据中的名字,此时的名字是什么呢?Spring Web MVC自动将简单类名(首字母小写)作为名字暴露,如“cn.javass.chapter6.model.UserModel”暴露的名字为“userModel”。

public @ModelAttribute List<String> test6()public @ModelAttribute List<UserModel> test7()   

对于集合类型(Collection接口的实现者们,包括数组),生成的模型对象属性名为“简单类名(首字母小写)”+“List”,如List生成的模型对象属性名为“stringList”,List生成的模型对象属性名为“userModelList”。

其他情况一律都是使用简单类名(首字母小写)作为模型对象属性名,如Map<String, UserModel>类型的模型对象属性名为“map”。

@SessionAttributes绑定命令对象到session

有时候我们需要在多次请求之间保持数据,一般情况需要我们明确的调用HttpSession的API来存取会话数据,如多步骤提交的表单。Spring Web MVC提供了@SessionAttributes进行请求间透明的存取会话数据。

//1、在控制器类头上添加@SessionAttributes注解  
@SessionAttributes(value = {"user"})    //①  
public class SessionAttributeController   //2、@ModelAttribute注解的方法进行表单引用对象的创建  
@ModelAttribute("user")    //②  
public UserModel initUser()   //3、@RequestMapping注解方法的@ModelAttribute注解的参数进行命令对象的绑定  
@RequestMapping("/session1")   //③  
public String session1(@ModelAttribute("user") UserModel user)  //4、通过SessionStatus的setComplete()方法清除@SessionAttributes指定的会话数据  
@RequestMapping("/session2")   //③  
public String session(@ModelAttribute("user") UserModel user, SessionStatus status) {  if(true) { //④  status.setComplete();  }  return "success";  
}

@SessionAttributes(value = {“user”})含义:

@SessionAttributes(value = {“user”}) 标识将模型数据中的名字为“user” 的对象存储到会话中(默认HttpSession),此处value指定将模型数据中的哪些数据(名字进行匹配)存储到会话中,此外还有一个types属性表示模型数据中的哪些类型的对象存储到会话范围内,如果同时指定value和types属性则那些名字和类型都匹配的对象才能存储到会话范围内。

包含@SessionAttributes的执行流程如下所示:

① 首先根据@SessionAttributes注解信息查找会话内的对象放入到模型数据中;

② 执行@ModelAttribute注解的方法:如果模型数据中包含同名的数据,则不执行@ModelAttribute注解方法进行准备表单引用数据,而是使用①步骤中的会话数据;如果模型数据中不包含同名的数据,执行@ModelAttribute注解的方法并将返回值添加到模型数据中;

③ 执行@RequestMapping方法,绑定@ModelAttribute注解的参数:查找模型数据中是否有@ModelAttribute注解的同名对象,如果有直接使用,否则通过反射创建一个;并将请求参数绑定到该命令对象;

此处需要注意:如果使用@SessionAttributes注解控制器类之后,③步骤一定是从模型对象中取得同名的命令对象,如果模型数据中不存在将抛出HttpSessionRequiredException Expected session attribute ‘user’(Spring3.1)

或HttpSessionRequiredException Session attribute ‘user’ required - not found in session(Spring3.0)异常。

④ 如果会话可以销毁了,如多步骤提交表单的最后一步,此时可以调用SessionStatus对象的setComplete()标识当前会话的@SessionAttributes指定的数据可以清理了,此时当@RequestMapping功能处理方法执行完毕会进行清理会话数据。

我们通过Spring Web MVC的源代码验证一下吧,此处我们分析的是Spring3.1的RequestMappingHandlerAdapter,读者可以自行验证Spring3.0的AnnotationMethodHandlerAdapter,流程一样:

(1、RequestMappingHandlerAdapter.invokeHandlerMethod

//1、RequestMappingHandlerAdapter首先调用ModelFactory的initModel方法准备模型数据:  
modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);  
//2、调用@RequestMapping注解的功能处理方法  
requestMappingMethod.invokeAndHandle(webRequest, mavContainer);  
//3、更新/合并模型数据  
modelFactory.updateModel(webRequest, mavContainer);   

(2、ModelFactory.initModel

Map<String, ?> attributesInSession = this.sessionAttributesHandler.retrieveAttributes(request);  
//1.1、将与@SessionAttributes注解相关的会话对象放入模型数据中  
mavContainer.mergeAttributes(attributesInSession);  
//1.2、调用@ModelAttribute方法添加表单引用对象  
invokeModelAttributeMethods(request, mavContainer);  
//1.3、验证模型数据中是否包含@SessionAttributes注解相关的会话对象,不包含抛出异常  
for (String name : findSessionAttributeArguments(handlerMethod)) {  if (!mavContainer.containsAttribute(name)) {  //1.4、此处防止在@ModelAttribute注解方法又添加了会话对象  //如在@ModelAttribute注解方法调用session.setAttribute("user", new UserModel());  Object value = this.sessionAttributesHandler.retrieveAttribute(request, name);  if (value == null) {  throw new HttpSessionRequiredException("Expected session attribute '" + name + "'");  }  mavContainer.addAttribute(name, value);  
}

(3、ModelFactory.invokeModelAttributeMethods

for (InvocableHandlerMethod attrMethod : this.attributeMethods) {  String modelName = attrMethod.getMethodAnnotation(ModelAttribute.class).value();   //1.2.1、如果模型数据中包含同名数据则不再添加  if (mavContainer.containsAttribute(modelName)) {  continue;  }  //1.2.2、调用@ModelAttribute注解方法并将返回值添加到模型数据中,此处省略实现代码  
}

(4、requestMappingMethod.invokeAndHandle 调用功能处理方法,此处省略

(5、ModelFactory.updateMode 更新模型数据

//3.1、如果会话被标识为完成,此时从会话中清除@SessionAttributes注解相关的会话对象  
if (mavContainer.getSessionStatus().isComplete()){   this.sessionAttributesHandler.cleanupAttributes(request);  
}  
//3.2、如果会话没有完成,将模型数据中的@SessionAttributes注解相关的对象添加到会话中  
else {  this.sessionAttributesHandler.storeAttributes(request, mavContainer.getModel());  
}  
//省略部分代码

到此@SessionAtrribute介绍完毕,测试代码在cn.javass.chapter6.web.controller.paramtype.SessionAttributeController中。

另外cn.javass.chapter6.web.controller.paramtype.WizardFormController是一个类似于【AbstractWizardFormController】多步骤提交表单需要考虑会话超时问题,这种方式可能对用户不太友好,我们可以采取隐藏表单(即当前步骤将其他步骤的表单隐藏)或表单数据存数据库(每步骤更新下数据库数据)等方案解决。

@Value绑定SpEL表示式

@Value用于将一个SpEL表达式结果映射到到功能处理方法的参数上。

public String test(@Value("#{systemProperties['java.vm.version']}") String jvmVersion)  

到此数据绑定我们就介绍完了,对于没有介绍的方法参数和注解(包括自定义注解)在后续章节进行介绍。接下来我们学习下数据类型转换吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot 的 RedisTemplate 的 execute 和 executePipelined 功能的区别redis

1.executespring 如下是 springboot 官网原文:springboot Redis provides support for transactions through the multi, exec, and discard commands. These operations are available on RedisTemplate, however RedisTemplate is not guaranteed to execute all operatio…

Error running ‘Tomcat‘: Unable to open debugger port (127.0.0.1:2148): java.net.SocketExceptio

在Web项目运行的时候&#xff0c;IDEA可能会报Error running ‘Tomcat’: Unable to open debugger port (127.0.0.1:2148): java.net.SocketException “socket closed”错误&#xff0c;启动不了Tomcat&#xff0c;在这种时候&#xff0c;网上的解决办法大多都是修改端口的这…

Java 枚举(enum) 详解7种常见的用法

JDK1.5引入了新的类型——枚举。在 Java 中它虽然算个“小”功能&#xff0c;却给我的开发带来了“大”方便。 用法一&#xff1a;常量 在JDK1.5 之前&#xff0c;我们定义常量都是&#xff1a; public static fianl… 。现在好了&#xff0c;有了枚举&#xff0c;可以把相关…

sqoop导入hive时间格式问题解决方案

sqoop导入hive时间格式问题解决方案 从mysql导入数据时,发现时间格式有问题,要么是时间后面多一位零,要么要使用时间戳,还能不能好好玩耍了?! 于是,我就逛论坛&#xff0c;找大神&#xff0c;最终无果&#xff0c;也许这个问题过于简单吧&#xff0c;居然没有大牛讨论。想了好…

Java枚举类型(enum)详解

文章目录理解枚举类型枚举的定义枚举实现原理枚举的常见方法Enum抽象类常见方法编译器生成的Values方法与ValueOf方法枚举与Class对象枚举的进阶用法向enum类添加方法与自定义构造函数关于覆盖enum类方法enum类中定义抽象方法enum类与接口枚举与switch枚举与单例模式EnumMapEnu…

mysql/sqlyog导入txt文件的方法

今天尝试着用sqlyog向mysql中导入数据&#xff0c;用了以下几种&#xff1a; 一、sql载入 格式&#xff1a; LOAD DATA LOCAL INFILE 文件路径 INTO TABLE 表名 FIELDS TERMINATED BY 字段分隔符 LINES TERMINATED BY 行分隔符;直接进去了 代码&#xff1a; LOAD DATA LOCA…

XSS知识总结

XSS基础 跨站脚本&#xff08;英语&#xff1a;Cross-site scripting&#xff0c;通常简称为&#xff1a;XSS&#xff09;是一种网站应用程序的安全漏洞攻击&#xff0c;是代码注入的一种。它允许恶意用户将代码注入到网页上&#xff0c;其他用户在观看网页时就会受到影响。这…

classmethod 继承_让人眼花缭乱的类继承

Python语言的一个优势是简洁易用。是否简洁易用仅仅是Python语言本身的一个话题&#xff0c;但“好消息”是如果你想创造那种一大堆继承、混乱的内部关系的代码&#xff0c;也是可以的&#xff01;今天烦人的代码来自于验证某些math-y数学分析代码。一开始&#xff0c;他们是发…

JAVA SSM框架+Redis 实现单点登录

1&#xff1a;什么是单点登录&#xff1f; 答&#xff1a;单点登录的英文名叫做&#xff1a;Single Sign On&#xff08;简称SSO&#xff09; 一般我们的模块都是在同一个系统下&#xff0c;同一个tomcat&#xff08;如图&#xff0c;以商城为例&#xff09; 后来为了维护和…

2017云栖大会门票转让_「揭秘GP」云栖大会 | Greenplum 6.0 内核优化解读和7.0展望...

9月25日&#xff0c;云栖大会在杭州阿里巴巴云栖小镇正式拉开序幕&#xff0c;三天会议期间&#xff0c;共吸引了200多位世界级科学家、400多家科技合作伙伴参与&#xff0c;科技展区面积超过3万平方米&#xff0c;共发布了1000多项顶尖技术。云栖大会现场在此次云栖大会上&…

从mysql到大数据(一)--开宗明义

一、大数据长什么样 长像很普通&#xff0c;至少看两眼后就觉得很平常。 举个栗子&#xff1a; 一个表格&#xff0c;学生信息表&#xff0c;里面有学号、姓名、性别、年龄、学校、学院、专业、年级、宿舍号等信息如下&#xff0c; 但是表在库里&#xff0c;我们想看&#xf…

SSO单点登录方案大全

分布式微服务系统主流常用的登录方案 前言: 单点登录其实是一个概念,主要是为了解决一次登录,多系统(本系统或外部系统)之间不需要重复登录的问题,就目前来说,主流的解决方案针对业务场景分为3个方向: 1: 同一公司,同父域下的单点登录解决方案. 如[http://map.baidu.com][[h…

em算法怎么对应原有分类_机器学习基础-EM算法

EM算法也称期望最大化(Expectation-Maximum,简称EM)算法&#xff0c;它是一个基础算法&#xff0c;是很多机器学习领域算法的基础&#xff0c;比如隐式马尔科夫算法(HMM)&#xff0c; LDA主题模型的变分推断等等。本文就对EM算法的原理做一个总结。EM算法要解决的问题我们经常会…

postman插件下载、安装教程

这里只讲如何在Chrome 中安装postman插件 下载链接&#xff1a;https://pan.baidu.com/s/1vampHeD0UiDNbrB3G8j_hA 提取码&#xff1a;wqdl 方法/步骤 1.在Chrome输入地址&#xff1a;[chrome://extensions/] 2.将压缩包直接拖拽至Chrome中 3.运行在Chrome输入地址&#xff…

得力条码扫描器怎么用_广东智能物流控制系统怎么选

广东智能物流控制系统怎么选&#xff0c;东莞智库&#xff0c;东莞智库(SmartWarehouse)&#xff0c;专注电子制造SMT智能仓库&#xff0c;致力于帮助电子制造企业提高物流仓储效率和效能。广东智能物流控制系统怎么选&#xff0c; 旭日东自动分拣系统是个集机械、电气、计算机…

从mysql到大数据(三)--mysql数据库建模一常用数据类型及引擎

数据库的安装请自行百度。如果你想直捣黄龙练查询&#xff0c;没有表没有数据是不能实现的。我们从建表开始学习。但要知道&#xff0c;我们所有东西都是了解&#xff0c;学习不要有压力&#xff0c;不要必须要求记什么&#xff0c;当然&#xff0c;如果你不累可以记&#xff0…

Postman用法简介-Http请求模拟工具

Postman用法简介-Http请求模拟工具 在我们平时开发中&#xff0c;特别是需要与接口打交道时&#xff0c;无论是写接口还是用接口&#xff0c;拿到接口后肯定都得提前测试一下&#xff0c;这样的话就非常需要有一个比较给力的Http请求模拟工具&#xff0c;现在流行的这种工具也…

matlab多元函数_函数的计算机处理8(1)_1MATLAB

计算机语言运用--数值计算8-函数的计算机处理8(1)_1MATLAB计算机&#xff1a;电子线路组成的计算机器。人与计算机则是通过计算机语言-符号系统说给计算机听而交流。计算机语言有低级语言-机器语言、汇编、高级语言-C/C/C#/VB/PASCAL/LISP/JAVA/PYTHON/……成百上千种之多。 作…

java 怎么通过url获取远程服务器上某个文件夹下的所有文件_JMX远程代码漏洞研究...

前言&#xff1a;前一段时间apace solr JMX因为配置不当出现远程代码执行漏洞&#xff0c;最近自己在看一套java系统时&#xff0c;发现该系统也存在JMX远程代码漏洞&#xff0c;于是乎就想研究下JMX这种通用型漏洞&#xff0c;下面我就从原理到利用对该漏洞做一个简单的梳理。…

app每秒并发数_性能测试连载 (38) jmeter 线程数与性能测试的负载模式

点击跳转>>jmeter--由浅入深学性能系列需求下面有3个场景&#xff0c;思考一下在jmeter里面如何设计场景1&#xff1a;有一个项目&#xff0c;500用户同时登录&#xff0c;响应时间能达到多少场景2&#xff1a;考勤打卡&#xff0c;最大吞吐量能达到多少(每秒最大能完成多…