前言:本文主要介绍SpringMVC控制器如何接收前台传送来的数据,包括通过SpringMVC自定义标签接收以及通过自定义接收对象接收。
本篇文章重点关注以下问题:
- SpringMVC自带的数据绑定标签来接收数据
- 自定义接收类型来接收数据(基本类型、自定义对象、复合对象、集合、数组等方式)
1. 通过SpringMVC自带的数据绑定标签来接收数据
首先看看控制器可以从前台发过来的请求内容:
注解 | 作用 |
@RequestParam | 绑定单个请求参数值 |
@PathVariable | 绑定URI模板变量值 |
@CookieValue | 绑定Cookie数据值 |
@RequestHeader | 绑定请求头数据 |
@ModelValue | 绑定参数到命令对象 |
@SessionAttributes | 绑定命令对象到session |
@RequestBody | 绑定请求的内容区数据并能进行自动类型转换等 |
@RequestPart | 绑定“multipart/data”数据,除了能绑定@RequestParam 能做到的请求参数外,还能绑定上传的文件等 |
1.1 测试@RequestParam:绑定单个请求参数值
@RequestParam用于将请求参数区数据映射到功能处理方法的参数上,其有三个参数:
- value:参数名字,即入参的请求参数名字;
- required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码;
- defaultValue:默认值,表示如果请求中没有同名参数时的默认值;
前台请求:
测试@RequestParam:绑定单个请求参数值(username=wj&age=11)
后台接收:
/** * @RequestParam 来映射请求参数, 绑定单个请求参数值. * * value 值即请求参数的参数名 * * required 该参数是否必须. 默认为 true * * defaultValue 请求参数的默认值 */ @RequestMapping(value = "dataBinder/testRequestParam.action") public String testRequestParam( @RequestParam(value = "username") String un, @RequestParam(value = "age", required = false, defaultValue = "0") int age) { System.out.println("【@RequestParam】username: " + un + ", age: " + age); return SUCCESS; }
1.2 测试@PathVariable:绑定URI模板变量值
@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上,其有三个参数:
- value:参数名字,即入参的请求参数名字;
- required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码;
- defaultValue:默认值,表示如果请求中没有同名参数时的默认值;
/** * @PathVariable 可以来映射 URL 中的占位符到目标方法的参数中. * @param id * @return */ @RequestMapping("dataBinder/testPathVariable/{id}.action") public String testPathVariable(@PathVariable("id") Integer id) { System.out.println("【@PathVariable】id = " + id); return SUCCESS; }
1.3 测试@CookieValue:绑定Cookie数据值
@CookieValue用于将请求的Cookie数据映射到功能处理方法的参数上,其有三个参数:
- value:参数名字,即入参的请求参数名字;
- required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码;
- defaultValue:默认值,表示如果请求中没有Cookie数据时的默认值;
前台代码:
测试@CookieValue:绑定Cookie数据值
后台代码:
/** * @CookieValue: 映射一个 Cookie 值 * * value 值即请求参数的参数名 * * required 该参数是否必须. 默认为 true * * defaultValue 请求参数的默认值 */ @RequestMapping("dataBinder/testCookieValue.action") public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) { System.out.println("【@CookieValue】 sessionId: " + sessionId); return SUCCESS; }
1.4 测试@RequestHeader:绑定请求头数据
@RequestHeader 用于将请求的头信息区数据映射到功能处理方法的参数上,其有三个参数:
- value:参数名字,即入参的请求参数名字;
- required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码;
- defaultValue:默认值,表示如果请求中没有同名参数时的默认值;
前台代码:
测试@RequestHeader:绑定请求头数据后台代码:
/** * @RequestHeader 来映射请求头. */ @RequestMapping("dataBinder/testRequestHeader.action") public String testRequestHeader(@RequestHeader(value = "Accept-Language") String al) { System.out.println("【RequestHeader】 Accept-Language = " + al); return SUCCESS; }
1.5 @ModelAttribute 绑定请求参数到命令对象
@ModelAttribute具有如下三个作用:
- 绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定流程,而且自动暴露为模型数据用于视图页面展示时使用;
- 暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象;
- 暴露@RequestMapping 方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。
1.5.1 绑定请求参数到命令对象
前台代码:
// 测试@ModelAttribute暴露表单引用对象 function onclick_ModelAttribute() { $.ajax({ url: "dataBinder/getModelAttribute.action", data : { "username" : "username_" }, type : 'post', dataType : "json", success: function(data){ var msg = "username : " + data.user.username + "\r\n" + "password : " + data.user.password; alert(msg); } }); }后台代码:
@RequestMapping("dataBinder/getModelAttribute.action") @ResponseBody public MapgetModelAttribute(@ModelAttribute("user") UserVo user){ /* 形参中的user与上述数据模型中的user为同一对象. */ System.out.println("【对象数组类型】" + user); Map map = new HashMap<>(); map.put("user", user); return map; }
1.5.2 暴露表单引用对象为模型数据
!-- 模拟修改操作 1. 原始数据为: 1, 熊燕子, 123456,[email protected],27 2. 密码不能被修改. 3. 表单回显, 模拟操作直接在表单填写对应的属性值 -->后台代码:
/**
* 有 @ModelAttribute 标记的方法, 会在每个目标方法执行之前被 SpringMVC 调用!
*/
@ModelAttribute
public void getUser(@RequestParam(value="id",required=false) Integer id, Map map){
System.out.println("【@ModelAttribute】【method】【ID】From Form");
if(id != null){
//模拟从数据库中获取对象
UserVo userVo = new UserVo(1, "wj", "123456", "[email protected]", 12);
System.out.println("从数据库中获取一个对象: " + userVo);
map.put("userVo", userVo);
}
}
@RequestMapping("dataBinder/testModelAttribute.action")
public String testModelAttribute(UserVo userVo){
System.out.println("【@ModelAttribute】修改: " + userVo);
return SUCCESS;
}
测试结果如下,可见@ModelAttribute 标记的方法会自动暴露表单引用对象为模型数据。
1.5.3 暴露@RequestMapping 方法返回值为模型数据
此方式不常用,后续文章介绍处理模型数据时会介绍,此处不展开。
1.6 测试@SessionAttributes:绑定命令对象到session
有时候我们需要在多次请求之间保持数据,一般情况需要我们明确的调用HttpSession的API来存取会话数据,如多步骤提交的表单。Spring Web MVC提供了@SessionAttributes进行请求间透明的存取会话数据。
前台代码:
测试@SessionAttributes:绑定命令对象到session后台代码:
@SessionAttributes(value={"userVo"}, types={String.class}) @RequestMapping("/views") @Controller public class DataBinderController { /** * @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(实际上使用的是 value 属性值), * 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用的是 types 属性值) * * 注意: 该注解只能放在类的上面. 而不能修饰放方法. */ @RequestMapping("dataBinder/testSessionAttributes.action") public String testSessionAttributes(Map测试结果:map){ System.out.println("【SessionAttributes】"); UserVo userVo = new UserVo("熊燕子", "123456", "[email protected]", 15); map.put("userVo", userVo); map.put("school", "南理工"); return SUCCESS; } }
在返回的页面上查看request域和session域,如下图所示,发现userVo和school都是既在request域也在session域中:
1.7 测试ServletAPI作为参数传入
ServletRequest/HttpServletRequest 和ServletResponse/HttpServletResponse,InputStream/OutputStream 和Reader/Writer,WebRequest/NativeWebRequest,HttpSession等都可以作为参数传入,此处仅传入部分最为样例。
前台代码:
测试ServletAPI作为参数传入后台代码:
@RequestMapping("dataBinder/testServletAPI.action") public void testServletAPI(HttpServletRequest request, HttpServletResponse response, Writer out) throws IOException { System.out.println("【ServletAPI】以参数传入" + request + ", " + response); out.write("hello springmvc"); }
2. 自定义接收类型来接收数据
前面是以表单提交数据,这里以ajax作为提交数据的方式。
2.1 参数绑定测试(基本数据类型)
前台代码:
// 基本类型 function onclick_basicType() { $.ajax({ url: "dataBinder/getBasicType.action", data : { count : $("#count").val() }, type : 'post', dataType : "json", success: function(data){ alert(data.count); } }); }后台代码:
@RequestMapping("dataBinder/getBasicType.action") @ResponseBody public MapgetBasicType(Integer count){ // 建议以包装类型接收,可不存在 System.out.println("【基本类型】count = " + count); Map map = new HashMap<>(); map.put("count", count); return map; }
2.2 参数绑定测试(自定义对象类型)
前台代码:
// 自定义对象 function onclick_Vo() { $.ajax({ url: "dataBinder/getVo.action", data : { username : $("#username_vo").val(), password : $("#password_vo").val() }, type : 'post', dataType : "json", success: function(data){ var msg = "username : " + data.user.username + "\r\n" + "password : " + data.user.password; alert(msg); } }); }后台代码(实体类UserVo定义见附件):
@RequestMapping("dataBinder/getVo.action") @ResponseBody public MapgetVo(UserVo user){ System.out.println("【自定义类型】" + user); Map map = new HashMap<>(); map.put("user", user); return map; }
2.3 参数绑定测试(自定义复合对象类型)
前台代码:
// 自定义复合对象 function onclick_CmpVo() { $.ajax({ url: "dataBinder/getCmpVo.action", data : { 'username' : $("#username_cvo").val(), 'password' : $("#password_cvo").val(), 'address.province' : $("#province_cvo").val(), 'address.city' : $("#city_cvo").val() }, type : 'post', dataType : "json", success: function(data){ var msg = "username : " + data.user.username + "\r\n" + "password : " + data.user.password + "\r\n" + "province : " + data.user.address.province + "\r\n" + "city : " + data.user.address.city + "\r\n"; alert(msg); } }); }后台代码(实体类UserVo定义见附件):
@RequestMapping("dataBinder/getCmpVo.action") @ResponseBody public MapgetCmpVo(UserVo user){ System.out.println("【自定义复合类型】" + user); Map map = new HashMap<>(); map.put("user", user); return map; }
2.4 参数绑定测试(List集合对象类型)
前台代码:
// List集合对象 function onclick_List() { $.ajax({ url: "dataBinder/getList.action", data : { 'users[0].username' : "username1", 'users[0].password' : "password1", 'users[0].address.province': '江苏', 'users[0].address.city' : '南京', 'users[1].username' : "username2", 'users[1].password' : "password2", 'users[2].username' : "username3", 'users[2].password' : "password3" }, type : 'post', dataType : "json", success: function(data){ alert("List集合参数传递成功..."); } }); }后台代码:
@RequestMapping("dataBinder/getList.action") @ResponseBody public MapUserListVo实体类如下:getList(UserListVo users){ System.out.println("【List集合】" + users); Map map = new HashMap<>(); map.put("users", users); return map; }
public class UserListVo { private Listusers; public List getUsers() { return users; } public void setUsers(List users) { this.users = users; } @Override public String toString() { return "UserListVo [users=" + users + "]"; } }
2.5 参数绑定测试(Map对象类型)
前台代码:
// Map对象 function onclick_Map() { $.ajax({ url: "dataBinder/getMap.action", data : { "users['a'].username" : "username1", "users['a'].password" : "password1", "users['a'].address.province" : "江苏", "users['a'].address.city" : "南京", "users['b'].username" : "username2", "users['b'].password" : "password2", "users['c'].username" : "username3", "users['c'].password" : "password3", }, type : 'post', dataType : "json", success: function(data){ alert("Map对象参数传递成功..."); } }); }
后台代码:
@RequestMapping("dataBinder/getMap.action") @ResponseBody public MapUserMapVo实体类如下:getMap(UserMapVo users){ System.out.println("【Map类型】" + users); Map map = new HashMap<>(); map.put("users", users); return map; }
public class UserMapVo { private Mapusers; public Map getUsers() { return users; } public void setUsers(Map users) { this.users = users; } @Override public String toString() { return "UserMapVo [users=" + users + "]"; } }
2.6 参数绑定测试(int数组类型)
前台代码:
// int数组类型 function onclick_ArrayInt() { var intArray = [1, 3, 5, 7, 9]; $.ajax({ url: "dataBinder/getArrayInt.action", data : { "intArray" : intArray }, type : 'post', dataType : "json", success: function(data){ alert("int数组类型传递成功..."); } }); }后台代码:
@RequestMapping("dataBinder/getArrayInt.action") @ResponseBody public MapgetArrayInt(@RequestParam("intArray[]") int[] intArray){ System.out.println("【int数组】" + Arrays.toString(intArray)); Map map = new HashMap<>(); map.put("success", true); return map; }
2.7 参数绑定测试(Vo对象数组类型)
前台代码:
// Vo对象数组类型 function onclick_ArrayVo() { $.ajax({ url: "dataBinder/getArrayVo.action", data : { "users[0].username" : "username1", "users[0].password" : "password1", "users[0].address.province" : "江苏", "users[0].address.address" : "南京", "users[1].username" : "username2", "users[1].password" : "password2", "users[2].username" : "username3", "users[2].password" : "password3", }, type : 'post', dataType : "json", success: function(data){ alert("对象数组类型传递成功..."); } }); }后台代码:
@RequestMapping("dataBinder/getArrayVo.action") @ResponseBody public MapUserArrayVo对象:getArrayVo(UserArrayVo users){ System.out.println("【对象数组类型】" + users); Map map = new HashMap<>(); map.put("success", true); return map; }
public class UserArrayVo { private UserVo[] users; public UserVo[] getUsers() { return users; } public void setUsers(UserVo[] users) { this.users = users; } @Override public String toString() { return "UserArrayVo [users=" + Arrays.toString(users) + "]"; } }
代码下载来源:http://super-wangj.iteye.com/blog/2388430