
* 而后是测试自定义接收类型
前言:本文主要介绍SpringMVC控制器如何接收前台传送来的数据,包括通过SpringMVC自定义标签接收以及通过自定义接收对象接收。
本篇文章重点关注以下问题:



首先看看控制器可以从前台发过来的请求内容:

SpringMVC内置注解以下注解用于提取请求中的内容:
| 注解 | 作用 |
| @RequestParam | 绑定单个请求参数值 |
| @PathVariable | 绑定URI模板变量值 |
| @CookieValue | 绑定Cookie数据值 |
| @RequestHeader | 绑定请求头数据 |
| @ModelValue | 绑定参数到命令对象 |
| @SessionAttributes | 绑定命令对象到session |
| @RequestBody | 绑定请求的内容区数据并能进行自动类型转换等 |
| @RequestPart | 绑定“multipart/data”数据,除了能绑定@RequestParam 能做到的请求参数外,还能绑定上传的文件等 |
@RequestParam用于将请求参数区数据映射到功能处理方法的参数上,其有三个参数:
前台请求:
<a href="dataBinder/testRequestParam.action?username=wj&age=11">测试@RequestParam:绑定单个请求参数值(username=wj&age=11)</a><br><br>
后台接收:
/**
* @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;
}@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上,其有三个参数:
<a href="dataBinder/testPathVariable/1.action">测试@PathVariable:绑定URI模板变量值{1}</a><br><br> 后台接收:/**
* @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;
}@CookieValue用于将请求的Cookie数据映射到功能处理方法的参数上,其有三个参数:
前台代码:
<a href="dataBinder/testCookieValue.action">测试@CookieValue:绑定Cookie数据值</a><br><br>
后台代码:
/**
* @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;
}@RequestHeader 用于将请求的头信息区数据映射到功能处理方法的参数上,其有三个参数:
前台代码:
<a href="dataBinder/testRequestHeader.action">测试@RequestHeader:绑定请求头数据</a><br><br>后台代码:
/**
* @RequestHeader 来映射请求头.
*/
@RequestMapping("dataBinder/testRequestHeader.action")
public String testRequestHeader(@RequestHeader(value = "Accept-Language") String al) {
System.out.println("【RequestHeader】 Accept-Language = " + al);
return SUCCESS;
}@ModelAttribute具有如下三个作用:
前台代码:
<div> <label>参数绑定测试(测试@ModelAttribute暴露表单引用对象):</label> <button onclick="onclick_ModelAttribute()">提交</button> </div>
// 测试@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 Map<String, Object> getModelAttribute(@ModelAttribute("user") UserVo user){
/* 形参中的user与上述数据模型中的user为同一对象. */
System.out.println("【对象数组类型】" + user);
Map<String, Object> map = new HashMap<>();
map.put("user", user);
return map;
}!--
模拟修改操作
1. 原始数据为: 1, 熊燕子, 123456,[email protected],27
2. 密码不能被修改.
3. 表单回显, 模拟操作直接在表单填写对应的属性值
-->
<form action="dataBinder/testModelAttribute.action" method="Post">
<input type="hidden" name="id" value="1"/>测试@ModelAttribute:绑定参数到命令对象<br>
username: <input type="text" name="username" value="熊燕子"/><br>
email: <input type="text" name="email" value="[email protected]"/><br>
age: <input type="text" name="age" value="27"/><br>
<input type="submit" value="Submit"/>
</form> 后台代码:/**
* 有 @ModelAttribute 标记的方法, 会在每个目标方法执行之前被 SpringMVC 调用!
*/
@ModelAttribute
public void getUser(@RequestParam(value="id",required=false) Integer id, Map<String, Object> 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 标记的方法会自动暴露表单引用对象为模型数据。
此方式不常用,后续文章介绍处理模型数据时会介绍,此处不展开。
有时候我们需要在多次请求之间保持数据,一般情况需要我们明确的调用HttpSession的API来存取会话数据,如多步骤提交的表单。Spring Web MVC提供了@SessionAttributes进行请求间透明的存取会话数据。
前台代码:
<a href="dataBinder/testSessionAttributes.action">测试@SessionAttributes:绑定命令对象到session</a>后台代码:
@SessionAttributes(value={"userVo"}, types={String.class})
@RequestMapping("/views")
@Controller
public class DataBinderController {
/**
* @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(实际上使用的是 value 属性值),
* 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用的是 types 属性值)
*
* 注意: 该注解只能放在类的上面. 而不能修饰放方法.
*/
@RequestMapping("dataBinder/testSessionAttributes.action")
public String testSessionAttributes(Map<String, Object> 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域中:

ServletRequest/HttpServletRequest 和ServletResponse/HttpServletResponse,InputStream/OutputStream 和Reader/Writer,WebRequest/NativeWebRequest,HttpSession等都可以作为参数传入,此处仅传入部分最为样例。
前台代码:
<a href="dataBinder/testServletAPI.action">测试ServletAPI作为参数传入</a>后台代码:
@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");
}前面是以表单提交数据,这里以ajax作为提交数据的方式。
前台代码:
<div>
<label>参数绑定测试(基本数据类型):</label>
<input id="count" name="count" value="10" type="text"/>
<button onclick="onclick_basicType()">提交</button>
</div>// 基本类型
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 Map<String, Object> getBasicType(Integer count){ // 建议以包装类型接收,可不存在
System.out.println("【基本类型】count = " + count);
Map<String, Object> map = new HashMap<>();
map.put("count", count);
return map;
}前台代码:
<div> <label>参数绑定测试(自定义对象类型):</label> <input id="username_vo" value="wang" type="text"/> <input id="password_vo" value="jun" type="text"/> <button onclick="onclick_Vo()">提交</button> </div>
// 自定义对象
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 Map<String, Object> getVo(UserVo user){
System.out.println("【自定义类型】" + user);
Map<String, Object> map = new HashMap<>();
map.put("user", user);
return map;
}前台代码:
<div> <label>参数绑定测试(自定义复合对象类型):</label><br> <input id="username_cvo" value="wang" type="text"/><br> <input id="password_cvo" value="jun" type="text"/><br> <input id="province_cvo" value="江苏" type="text"/><br> <input id="city_cvo" value="南京" type="text"/> <button onclick="onclick_CmpVo()">提交</button> </div>
// 自定义复合对象
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 Map<String, Object> getCmpVo(UserVo user){
System.out.println("【自定义复合类型】" + user);
Map<String, Object> map = new HashMap<>();
map.put("user", user);
return map;
}前台代码:
<div> <label>参数绑定测试(List集合对象类型):</label> <button onclick="onclick_List()">提交</button> </div>
// 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 Map<String, Object> getList(UserListVo users){
System.out.println("【List集合】" + users);
Map<String, Object> map = new HashMap<>();
map.put("users", users);
return map;
} UserListVo实体类如下:public class UserListVo {
private List<UserVo> users;
public List<UserVo> getUsers() {
return users;
}
public void setUsers(List<UserVo> users) {
this.users = users;
}
@Override
public String toString() {
return "UserListVo [users=" + users + "]";
}
}前台代码:
<div> <label>参数绑定测试(Map对象类型):</label> <button onclick="onclick_Map()">提交</button> </div>
// 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 Map<String, Object> getMap(UserMapVo users){
System.out.println("【Map类型】" + users);
Map<String, Object> map = new HashMap<>();
map.put("users", users);
return map;
} UserMapVo实体类如下:public class UserMapVo {
private Map<String, UserVo> users;
public Map<String, UserVo> getUsers() {
return users;
}
public void setUsers(Map<String, UserVo> users) {
this.users = users;
}
@Override
public String toString() {
return "UserMapVo [users=" + users + "]";
}
}前台代码:
<div> <label>参数绑定测试(int数组类型):</label> <button onclick="onclick_ArrayInt()">提交</button> </div>
// 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 Map<String, Object> getArrayInt(@RequestParam("intArray[]") int[] intArray){
System.out.println("【int数组】" + Arrays.toString(intArray));
Map<String, Object> map = new HashMap<>();
map.put("success", true);
return map;
}前台代码:
<div> <label>参数绑定测试(Vo对象数组类型):</label> <button onclick="onclick_ArrayVo()">提交</button> </div>
// 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 Map<String, Object> getArrayVo(UserArrayVo users){
System.out.println("【对象数组类型】" + users);
Map<String, Object> map = new HashMap<>();
map.put("success", true);
return map;
} UserArrayVo对象: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) + "]";
}
}