今天对spring mvc 接收参数的几种方式做了一个整理,方便日后回顾。
一,搭建sping + spring mvc 项目环境,这个之前有讲过,可以直接拷贝工程做测试用,这里就不重复了。
二,新建测试类,SpringController
每个请求都已经注释清楚了,直接访问测试即可。
package com.maven.web.controller;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import com.maven.web.entity.UserInfo;
/**
* 测试springmvc接收参数的几种方式
* @author Administrator
*
*/
//统一返回json数据到前端,不必在方法上添加@ResponseBody注解
@RestController
public class SpringController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 1,form表单提交
* 可以直接通过参数名获取,
* 不添加注解时
* 注意参数名要和表单name一致,否则获取不到参数值,结果为null
*
* 添加注解@RequestParam时,
* 可以设置参数必须传递required=ture,
* 如果没有则会抛异常:Required String parameter 'password' is not present
* 可以给参数设置默认值defaultValue="0000"
* 有默认值的情况下,required属性无效
*
* @param userName
* @param password
*/
@RequestMapping(value="/name/form/post/or/get",method={RequestMethod.POST,RequestMethod.GET})
public void formPost(String userName,
@RequestParam(value="password",required=true,defaultValue="0000") String password){
logger.info("form表单提交,通过参数名接收");
logger.info("name:"+userName+",gender:"+password);
}
/**
*,2,form表单提交
* 用一个实体bean来接收表单整体数据,注意bean的属性要和表单name一致
* 只有表单name与bean中属性值一致才会正确赋值,否则bean获取到的值为null
* 可以不添加任何注解
* 也可以添加注解 @ModelAttribute,括号里的别名可以任意取,也可以不填
* 不能添加@RequestBody注解,会抛异常
*
* @param userInfo
*/
@RequestMapping(value="/bean/form/post/or/get",method={RequestMethod.POST,RequestMethod.GET})
public void formPost(@ModelAttribute UserInfo userInfo,String testParam){
logger.info("form表单提交,通过实体类接收,映射不到的属性,通过参数名接收");
logger.info("userInfo:"+userInfo);
logger.info("testParam:"+testParam);
}
/**
* 表单提交,相同参数名可以用数组接收
* post,get请求是一样的
* @param userName
*/
@RequestMapping(value="/array/form/post/or/get",method={RequestMethod.POST,RequestMethod.GET})
public void formPost(String[] userName,String testParam){
logger.info("form表单提交,用数组接收相同参数名");
logger.info("userName:"+Arrays.toString(userName));
logger.info("testParam:"+testParam);
}
/**
* 链接请求
* 从url后面获取参数
* 必须使用@PathVariable注解
*
* @param userName
* @param password
*/
@RequestMapping(value="/link/get/{name}/{pwd}",method=RequestMethod.GET)
public void linkGetPath(@PathVariable("name") String userName,
@PathVariable("pwd") String password){
logger.info("通过链接/link/get/{name}/{pwd}访问传递参数");
logger.info("name:"+userName+",gender:"+password);
}
/**
* 链接请求
* 从url后面获取参数
* 可以使用@RequestParam注解,value必须跟传递的参数名一致
* 这里和表单get请求一样
*
* @param userName
* @param password
*/
@RequestMapping(value="/link/get/params",method=RequestMethod.GET)
public void linkGetParams(@RequestParam(value="name") String userName,
@RequestParam(value="pwd") String password){
logger.info("通过链接/link/get/params?name=&pwd=访问传递参数");
logger.info("name:"+userName+",gender:"+password);
}
/**
* 链接请求
* 从url后面获取参数
* 可以直接用参数名获取,不加注解,但是参数名要和传递的参数名一致
* 这里和表单get请求一样
*
* @param userName
* @param password
*/
@RequestMapping(value="/link/get",method=RequestMethod.GET)
public void linkGet(String userName,String password){
logger.info("通过链接/link/get?userName=&password=访问传递参数");
logger.info("name:"+userName+",gender:"+password);
}
/**
* 链接请求
* 通过url传递的参数也可以直接用java bean来接收
* 同表单提交一样,这里不需要加注解即可获取到
*
* @param userInfo
*/
@RequestMapping(value="/bean/link/get",method=RequestMethod.GET)
public void linkGet(UserInfo userInfo){
logger.info("通过链接/link/get?userName=&password=访问传递参数");
logger.info("userInfo:"+userInfo);
}
/**
* ajax请求,参数为json字符串
* get请求,同上,可以用参数名获取json字符串,然后后台对json字符串做处理
*
* @param userInfo
*/
@RequestMapping(value="/ajax/get",method=RequestMethod.GET)
public String ajaxGet(String json){
logger.info("ajax发送get请求,参数为json字符串");
logger.info("json:"+json);
UserInfo userInfo = JSON.parseObject(json, UserInfo.class);
logger.info("userInfo:"+userInfo);
return "success";
}
/**
* ajax请求,参数为json字符串
* post请求,必须添加@RequestBody注解,利用spring框架将json串转成java bean
* java bean 属性名称要和json字符串一致
*
* @param userInfo
*/
@RequestMapping(value="/ajax/post",method=RequestMethod.POST)
public String ajaxPost(@RequestBody UserInfo userInfo){
logger.info("ajax发送post请求,参数为json字符串");
logger.info("userInfo:"+userInfo);
return "success";
}
/**
* 测试json字符串是否可以直接用参数名获取
* 结果:不能获取到参数,加上注解@RequestParam也不行
* 可以加上注解@RequestBody,然后用String接收到整个json字符串
*
* @param json
* @return
*/
@RequestMapping(value="/ajax/post/params",method=RequestMethod.POST)
public String ajaxPostParams(@RequestBody String json){
logger.info("ajax发送post请求,参数为json字符串");
logger.info("json:"+json);
return "success";
}
/**
* ajax发送数组格式的字符串,
* 实际是数组格式的字符串,需要手动转换成数组对象
* @param params
* @return
*/
@RequestMapping(value="/ajax/post/arr",method=RequestMethod.POST)
public String ajaxPostArr(@RequestBody String params){
logger.info("ajax传递数组格式的字符串");
logger.info("params:"+params);
String[] arr = JSON.parseObject(params, String[].class);
logger.info(Arrays.toString(arr));
return "success";
}
/**
* ajax直接传递数组对象,同时还可以传递其他参数,
* 类似表单提交,注意要设置:
* traditional:true
* contentType:默认
*
* @param params
* @return
*/
@RequestMapping(value="/ajax/post/arr2",method={RequestMethod.POST,RequestMethod.GET})
public String ajaxPostArr2(String[] params,String name){
logger.info("ajax传递数组对象");
logger.info(Arrays.toString(params));
logger.info("name:"+name);
return "success";
}
}
前端测试代码:
form.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<span style="font-size: 12px;color:red;">后台直接使用参数名获取表单参数,get,post请求一样</span>
<form id="form1" action="/com.maven.web/name/form/post/or/get" method="get">
<label>用户名</label> <input type="text" id="name" name="userName" /> <br />
<button
οnclick="function(){document.getElementById('form1').submit();}">提交</button>
</form>
<br/>
<br/>
<span style="font-size: 12px;color:red;">后台直接使用java bean获取表单参数,get,post请求一样</span>
<form id="form2" action="/com.maven.web/bean/form/post/or/get" method="get">
<label>用户名</label> <input type="text" id="name" name="userName" />
<br />
<label>密码</label> <input type="text" id="password" name="password" />
<br />
<label>其他参数</label> <input type="text" name="testParam" />
<br />
<button
οnclick="function(){document.getElementById('form2').submit();}">提交</button>
</form>
<br/>
<br/>
<span style="font-size: 12px;color:red;">后台使用String[]获取表单参数,get,post请求一样</span>
<form id="form3" action="/com.maven.web/array/form/post/or/get" method="get">
<label>用户名</label> <input type="text" name="userName" /> <br />
<label>用户名</label> <input type="text" name="userName" /> <br />
<label>其他参数</label> <input type="text" name="testParam" /><br />
<br />
<button
οnclick="function(){document.getElementById('form3').submit();}">提交</button>
</form>
<br/>
<br/>
<span style="font-size: 12px;color:red;">发送链接,从url后面获取参数</span>
<br/>
<a href="http://localhost:8088/com.maven.web/link/get/aa/bb">链接1:/link/get/aa/bb,,通过注解@PathVariable获取</a>
<br/>
<a href="http://localhost:8088/com.maven.web/link/get/params?name=aa&pwd=bb">链接2:/link/get?name=aa&pwd=bb,通过注解@RequestParam获取</a>
<br/>
<a href="http://localhost:8088/com.maven.web/link/get?userName=aa&password=bb">链接3:/link/get?userName=aa&password=bb,直接通过注解参数名获取</a>
<br/>
<a href="http://localhost:8088/com.maven.web/bean/link/get?userName=aa&password=bb">链接4:/bean/link/get?userName=aa&password=bb,通过java bean获取</a>
</body>
</html>
ajax.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="./jquery-2.1.1.js"></script>
<script type="text/javascript">
/**
* ajax get请求,通过url传递参数
* 后台接收到json的字符串,可以自行转换成对象
*/
function sendGet(){
var data = {'userName':'aaa','password':'0000'};
var json = JSON.stringify(data);
$.ajax({
method : 'GET',
data:{'json':json},
url : '/com.maven.web/ajax/get',
dataType : 'json',//返回数据格式
success : function(result) {
alert('success');
},
error : function(err) {
alert("error");
}
});
};
/**
* post请求,传递json格式数据,后台可以直接用实体bean接收
* contentType : 'application/json'
*/
function sendPost(){
var data = {'userName':'aaa','password':'0000'};
var json = JSON.stringify(data);
$.ajax({
method : 'POST',
url : '/com.maven.web/ajax/post',
data : json,
dataType : 'json',//返回数据格式
contentType : 'application/json',//必须为false
success : function(result) {
alert('success');
},
error : function(err) {
alert("error");
}
});
};
/**
* post 传递json格式数据,后台如果不用实体bean接收,可以直接用String接收
* 获取到json串然后自行转换成对象
*/
function sendPostParams(){
var data = {'userName':'aaa','password':'0000'};
var json = JSON.stringify(data);
$.ajax({
method : 'POST',
url : '/com.maven.web/ajax/post/params',
data : json,
dataType : 'json',//返回数据格式
contentType : 'application/json',
success : function(result) {
alert('success');
},
error : function(err) {
alert("error");
}
});
};
/**
* 通过json字符串的格式传递数组,后台需要手动获取参数转换成数组
* 如果只有一个参数,后台可以直接获取,但是如果有多个,后台必须封装成java bean来获取
* 属性对应json传递的参数名
*/
function sendPostArr(){
var _list = [];
for (var i = 0; i < 5; i++) {
_list[i] = 'a'+i;
}
var data = {'params':_list};
var json = JSON.stringify(_list);
$.ajax({
method : 'POST',
url : '/com.maven.web/ajax/post/arr',
data : json,
dataType : 'json',//返回数据格式
contentType : 'application/json',
success : function(result) {
alert('success');
},
error : function(err) {
alert("error");
}
});
};
/**
* 直接传递数组对象,后台可以用数组直接接收
* 这是模拟表单提交数据,可以直接传递参数
* 注意,传递数组的话,必须设置traditional: true
* 这里设置get,post请求都一样
*/
function sendPostArr2(){
var _list = [];
for (var i = 0; i < 5; i++) {
_list[i] = 'a'+i;
}
$.ajax({
method : 'GET',
url : '/com.maven.web/ajax/post/arr2',
data : {'params':_list,'name':'aaa'},
traditional: true,//当设置成true的时候就会用传统方式序列化参数
dataType : 'json',
success : function(result) {
alert('success');
},
error : function(err) {
alert("error");
}
});
};
</script>
</head>
<body>
<span style="font-size: 12px;color:red;">ajax请求发送json字符串,后台不能直接用参数名获取</span>
<br/>
<a href="#" οnclick="sendGet()">ajax get请求,后台可以直接用参数名接收</a>
<br/>
<br/>
<a href="#" οnclick="sendPost()">ajax post请求,后台用注解@RequestBody+java bean接收参数</a>
<br/>
<br/>
<a href="#" οnclick="sendPostParams()">ajax post请求,后台用注解@RequestBody+String接收整个json串</a>
<br/>
<br/>
<a href="#" οnclick="sendPostArr()">ajax post请求通过json字符串的格式传递数组,后台需要手动获取参数转换成数组</a>
<br/>
<br/>
<a href="#" οnclick="sendPostArr2()">ajax直接传递数组对象,后台可以用数组直接接收,post,get请求都一样</a>
</body>
</html>
访问测试,界面如下,查看后台控制台打印消息测试结果。
可以看到,ajax请求既支持json格式,也支持表单格式。
那么怎么选择这两种方式呢?这不是一个非错即对的选择,但可以参考如下的实践建议:
如果数据是简单、平面的key-value数值对,那么使用www-form-urlencoded简单实用,不需要额外的编解码;
如果数据是复杂的嵌套关系,有多层数据,那么使用json会简化数据的处理,从而更高效。