[转载]SpringBoot系列: SpringMVC 参数绑定注解解析
本文转载自 https://www.cnblogs.com/morethink/p/8028664.html, 作者写得非常好, 致谢!
SpringMVC 参数绑定注解解析
本文介绍了用于参数绑定的相关注解。
绑定:将请求中的字段按照名字匹配的原则填入模型对象。
SpringMVC就跟Struts2一样,通过拦截器进行参数匹配。
代码在 https://github.com/morethink/MySpringMVC
URI模板变量
这里指uri template中variable(路径变量),不含queryString部分
@PathVariable
当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariable注解绑定它传过来的值到方法的参数上。
示例代码:
@RestController
@RequestMapping("/users")
public class UserAction {
@GetMapping("/{id}")
public Result getUser(@PathVariable int id) {
return ResultUtil.successResult("123456");
}
}
上面代码把URI template 中变量 ownerId的值和petId的值,绑定到方法的参数上。若方法参数名称和需要绑定的uri template中变量名称不一致,需要在@PathVariable("name")指定uri template中的名称。
请求头
@RequestHeader
@RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上。
示例代码:
这是一个Request 的header部分:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:8080
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36
@GetMapping("/getRequestHeader")
public Result getRequestHeader(@RequestHeader("Accept-Encoding") String encoding) {
return ResultUtil.successResult(encoding);
}
上面的代码,把request header部分的 Accept-Encoding的值,绑定到参数encoding上。
@CookieValue
可以把Request header中关于cookie的值绑定到方法的参数上。
例如有如下Cookie值:JSESSIONID=588DC770E582A3189B7E6210102EAE02
参数绑定的代码:
@RequestMapping("/getCookie")
public Result getCookie(@CookieValue("JSESSIONID") String cookie) {
return ResultUtil.successResult(cookie);
}
即把JSESSIONID的值绑定到参数cookie上。
请求体
@RequestParam
- 常用来处理简单类型的绑定,通过Request.getParameter() 获取的String可直接转换为简单类型的情况( String--> 简单类型的转换操作由ConversionService配置的转换器来完成);因为使用request.getParameter()方式获取参数,所以可以处理get 方式中queryString的值,也可以处理post方式中 body data的值;
- 用来处理Content-Type: 为
application/x-www-form-urlencoded编码的内容,提交方式GET、POST; - 该注解有两个属性: value、required; value用来指定要传入值的id名称,required用来指示参数是否必须绑定;
示例代码:
@GetMapping("/tesRequestParam")
public Result tesRequestParam(@RequestParam("username") String username) {
return ResultUtil.successResult(username);
}
@RequestBody
该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;
它是通过使用HandlerAdapter 配置的HttpMessageConverters来解析post data body,然后绑定到相应的bean上的。
因为配置有FormHttpMessageConverter,所以也可以用来处理 application/x-www-form-urlencoded的内容,处理完的结果放在一个MultiValueMap<String, String>里,这种情况在某些特殊需求下使用,详情查看FormHttpMessageConverter api;
示例代码:
@PostMapping("/tesRequestBody")
public Result tesRequestBody(@RequestBody User user) {
return ResultUtil.successResult(user);
}
结果截图:

Content-Type:application/json
@RequestBody通过list接收对象数组
在我们传递对象的时候,无论Content-Type是x-www-form-urlencoded还是application/json其实没有多大的关系,可是当我们需要传递对象数组的时候,表单编码就不行了,这时我们是可以采用json传递,然后后台使用@RequestBody注解,通过list接收来对象数组。
前端代码:
index.html
//打开页面时运行
$(document).ready(function () {
var users = [];
var user1 = {"username": "dd", "password": "123"};
var user2 = {"username": "gg", "password": "123"};
users.push(user1);
users.push(user2);
$.ajax({
type: "POST",
url: "users/saveUsers",
timeout: 30000,
dataType: "json",
contentType: "application/json",
data: JSON.stringify(users),
success: function (data) {
//将返回的数据展示成table
showTable(data);
},
error: function () { //请求出错的处理
$("#result").text("请求出错");
}
});
});
后台代码:
@PostMapping("saveUsers")
public Result saveUsers(@RequestBody List<User> users) {
return ResultUtil.successResult(users);
}
结果截图:

表格展示数据
@SessionAttribute
该注解用来绑定HttpSession中的attribute对象的值,便于在方法中的参数里使用。该注解有value、types两个属性,可以通过名字和类型指定要使用的attribute 对象
示例代码:
@PostMapping("/setSessionAttribute")
public Result setSessionAttribute(HttpSession session, String attribute) {
session.setAttribute("attribute", attribute);
return ResultUtil.SUCCESS_RESULT;
}
@GetMapping("/getSessionAttribute")
public Result getSessionAttribute(@SessionAttribute("attribute") String attribute) {
return ResultUtil.successResult(attribute);
}
我们首先给session添加一个attribute,然后再取出这个attribute。

添加属性

得到属性
@ModelAttribute
@ModelAttribute标注可被应用在方法或方法参数上。
方法使用@ModelAttribute标注
标注在方法上的@ModelAttribute说明方法是用于添加一个或多个属性到model上。这样的方法能接受与@RequestMapping标注相同的参数类型,只不过不能直接被映射到具体的请求上。
在同一个控制器中,标注了@ModelAttribute的方法实际上会在@RequestMapping方法之前被调用。
以下是示例:
// Add one attribute
// The return value of the method is added to the model under the name "account"
// You can customize the name via @ModelAttribute("myAccount")
@ModelAttribute
public Account addAccount(@RequestParam String number) {
return accountManager.findAccount(number);
}
// Add multiple attributes
@ModelAttribute
public void populateModel(@RequestParam String number, Model model) {
model.addAttribute(accountManager.findAccount(number));
// add more ...
}
@ModelAttribute方法通常被用来填充一些公共需要的属性或数据,比如一个下拉列表所预设的几种状态,或者宠物的几种类型,或者去取得一个HTML表单渲染所需要的命令对象,比如Account等。
@ModelAttribute标注方法有两种风格:
- 在第一种写法中,方法通过返回值的方式默认地将添加一个属性;
- 在第二种写法中,方法接收一个Model对象,然后可以向其中添加任意数量的属性。
可以在根据需要,在两种风格中选择合适的一种。
一个控制器可以拥有多个@ModelAttribute方法。同个控制器内的所有这些方法,都会在@RequestMapping方法之前被调用。
@ModelAttribute方法也可以定义在@ControllerAdvice标注的类中,并且这些@ModelAttribute可以同时对许多控制器生效。
属性名没有被显式指定的时候又当如何呢?在这种情况下,框架将根据属性的类型给予一个默认名称。举个例子,若方法返回一个Account类型的对象,则默认的属性名为"account"。可以通过设置@ModelAttribute标注的值来改变默认值。当向Model中直接添加属性时,请使用合适的重载方法addAttribute(..)-即带或不带属性名的方法。
@ModelAttribute标注也可以被用在@RequestMapping方法上。这种情况下,@RequestMapping方法的返回值将会被解释为model的一个属性,而非一个视图名,此时视图名将以视图命名约定来方式来确定。
方法参数使用@ModelAttribute标注
标注在方法参数上的@ModelAttribute说明了该方法参数的值将由model中取得。如果model中找不到,那么该参数会先被实例化,然后被添加到model中。在model中存在以后,请求中所有名称匹配的参数都会填充到该参数中。
这在Spring MVC中被称为数据绑定,一个非常有用的特性,我们不用每次都手动从表格数据中转换这些字段数据。
@PostMapping
public Result saveUser(@ModelAttribute User user) {
return ResultUtil.successResult(user);
}
以上面的代码为例,这个User类型的实例可能来自哪里呢?有几种可能:
- 它可能因为
@SessionAttributes标注的使用已经存在于model中 - 它可能因为在同个控制器中使用了
@ModelAttribute方法已经存在于model中,正如上一小节所叙述的 - 它可能是由URI模板变量和类型转换中取得的
- 它可能是调用了自身的默认构造器被实例化出来的
@ModelAttribute方法常用于从数据库中取一个属性值,该值可能通过@SessionAttributes标注在请求中间传递。在一些情况下,使用URI模板变量和类型转换的方式来取得一个属性是更方便的方式。
在不给定注解的情况下,参数是怎样绑定的?
通过分析AnnotationMethodHandlerAdapter和RequestMappingHandlerAdapter的源代码发现,方法的参数在不给定参数的情况下:
- 若要绑定的对象时简单类型:调用
@RequestParam来处理的。
这里的简单类型指Java的原始类型(boolean, int 等)、原始类型对象(Boolean, Int等)、String、Date等ConversionService里可以直接String转换成目标对象的类型。也就是说没有特别需求,不推荐使用@RequestParam。 - 若要绑定的对象时复杂类型:调用
@ModelAttribute来处理的。也就是说如果不需要从model或者session中得到数据,@ModelAttribute可以不使用。
@RequestMapping支持的方法参数
下面这些参数Spring在调用请求方法的时候会自动给它们赋值,所以当在请求方法中需要使用到这些对象的时候,可以直接在方法上给定一个方法参数的申明,然后在方法体里面直接用就可以了。
- HttpServlet 对象,主要包括HttpServletRequest 、HttpServletResponse 和HttpSession 对象。 但是有一点需要注意的是在使用HttpSession 对象的时候,如果此时HttpSession 对象还没有建立起来的话就会有问题。
- Spring 自己的WebRequest 对象。 使用该对象可以访问到存放在HttpServletRequest 和HttpSession 中的属性值。
- InputStream 、OutputStream 、Reader 和Writer 。 InputStream 和Reader 是针对HttpServletRequest 而言的,可以从里面取数据;OutputStream 和Writer 是针对HttpServletResponse 而言的,可以往里面写数据。
- 使用
@PathVariable、@RequestParam、@CookieValue和@RequestHeader标记的参数。 - 使用
@ModelAttribute标记的参数。 - java.util.Map 、Spring 封装的Model 和ModelMap 。 这些都可以用来封装模型数据,用来给视图做展示。
- 实体类。 可以用来接收上传的参数。
- Spring 封装的MultipartFile 。 用来接收上传文件的。
- Spring 封装的Errors 和BindingResult 对象。 这两个对象参数必须紧接在需要验证的实体对象参数之后,它里面包含了实体对象的验证结果。
一个参数传多个值
在浏览器输入此URLhttp://localhost:8080/admin/login.action?username=geek&password=geek&password=geek
结果得到的对象为 : Manager{username='geek', password='geek,geek'}
参考文档:
[转载]SpringBoot系列: SpringMVC 参数绑定注解解析的更多相关文章
- SpringMVC 参数绑定注解解析
本文介绍了用于参数绑定的相关注解. 绑定:将请求中的字段按照名字匹配的原则填入模型对象. SpringMVC就跟Struts2一样,通过拦截器进行参数匹配. 代码在 https://github.co ...
- SpringMVC参数绑定,这篇就够了!
SpringMVC参数绑定,简单来说就是将客户端请求的key/value数据绑定到controller方法的形参上,然后就可以在controller中使用该参数了 下面通过5个常用的注解演示下如何进行 ...
- 一篇文章搞定SpringMVC参数绑定
SpringMVC参数绑定,简单来说就是将客户端请求的key/value数据绑定到controller方法的形参上,然后就可以在controller中使用该参数了 下面通过5个常用的注解演示下如何进行 ...
- Spring MVC-学习笔记(3)参数绑定注解、HttpMessageConverter<T>信息转换、jackson、fastjson、XML
1.参数绑定注解 1>@RequestParam: 用于将指定的请求参数赋值给方法中的指定参数.支持的属性: 2>@PathVariable:可以方便的获得URL中的动态参数,只支持一个属 ...
- 【转】@RequestParam @RequestBody @PathVariable 等参数绑定注解详解
@RequestParam @RequestBody @PathVariable 等参数绑定注解详解 2014-06-02 11:24 23683人阅读 评论(2) 收藏 举报 目录(?)[+] 引言 ...
- SpringMvc参数绑定出现乱码解决方法
在SpringMvc参数绑定过程中出现乱码的解决方法 1.post参数乱码的解决方法 在web.xml中添加过滤器 <!-- 过滤器 处理post乱码 --> <filter> ...
- SpringMVC参数绑定(未完待续)
1. Strut2与SpringMVC接收请求参数的区别 Struts2通过action类的成员变量接收SpringMVC通过controller方法的形参接收 2. SpringMVC参数绑定流程 ...
- 转载:@RequestParam @RequestBody @PathVariable 等参数绑定注解详解
转载自:https://blog.csdn.net/walkerjong/article/details/7946109#commentBox 因为写的很好很全,所以转载过来 引言:接上一篇文章, ...
- SpringMvc之参数绑定注解详解之三
2. @RequestHeader.@CookieValue @RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上. 示例代码: 这是一个Request ...
随机推荐
- Min_25
可以用来筛出一个积性函数的前缀和.这个积性函数要满足当\(x\)是质数时,\(f(x)\)可以快速求出,\(f(x^k)\)也可以快速算出. 首先我们要处理出一个\(g(x)=\sum_{x\in p ...
- linux系统下saltstack的安装和配置
Saltstack是一个新的基础设施管理工具,两大功能:远程执行和配置管理. Saltstack使用Python开发,是一个非常简单易用和轻量级的管理工具.由Master和Minion构成,通过Zer ...
- [USACO08DEC]在农场万圣节Trick or Treat on the Farm【Tarja缩点+dfs】
题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节. 由于牛棚不太大,FJ通过指定奶牛必须遵 ...
- [HNOI2007]梦幻岛宝珠(背包)
给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值.数据范围:N<=100;W<=2^30,并且保证每颗宝石的重量符 ...
- 20165223《Java程序设计》第八周Java学习总结
教材学习内容总结 第12章-JAVA多线程机制 要点 Java中的线程 Thread类与线程的创建 线程的常用方法 线程同步 协调同步的线程 线程联合 GUI线程 计时器线程 教材学习中的问题和解决过 ...
- JavaScript深入之执行上下文栈
如果要问到 javascript 代码执行顺序的话,想必写过javascript的开发者都会有个直观的印象,那就是顺序执行,例如: var foo = function(){ console.log( ...
- flask Blueprint蓝图
首先要了解蓝图的作用,模拟场景在团队开发过程中团队每个人都在写自己负责的功能模块,那多个py文件模板,我们如果完成后需要运行是不是要运行多个服务?但是我们的项目是一个整体,而不是零散的,所以我们怎么把 ...
- 第九篇-新建文件夹和文本文件mkdirs,createNewFile
一.新建一个empty activity的项目 二.修改AndroidMainfest.xml,添加用户权限. <?xml version="1.0" encoding=&q ...
- Redis高并发和快速的原因
一.Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接 ...
- 构造代码块、this关键字、静态变量、静态代码块、主函数
一.构造代码块: 作用:给对象进行初始化. 特点:对象一经运行就执行(与变量声明时赋初值同级别,此处注意 非法前向引用) 优先于构造函数的执行. 与构造函数的区别: 构造代码块是给所有对象统一初始化. ...