一、四种接收提交参数的方式
1. 方法参数直接接收表单域的值。
简单的表单如下:
<form action="${pageContext.request.contextPath}/submit" method="POST">
<input type="text" name="id" />
<input type="text" name="name" />
<input type="submit" value="提交" />
</form>
接收时直接指定参数名称为表单域名:
@RequestMapping("/submit")
public String submit(String name, String id){
System.out.println(id);
System.out.println(name);
return "test";
}
2. 使用最初的HttpServletRequest对象的getParameter方法来获取值
@RequestMapping("/submit")
public String submit(HttpServletRequest request){
System.out.println(request.getParameter("id"));
System.out.println(request.getParameter("name"));
return "test";
}
3. 用bean来接收
准备一个bean,其中setter/getter可以部分跟对应参数对应。
public class Tag {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() { return name; }
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Tag [id=").append(id)
.append(", name=").append(name)
.append("]");
return builder.toString();
}
}
然后接收的时候:
@RequestMapping("/submit")
public String submit(Tag tag){
System.out.println(tag);
return "test";
}
4. 通过发送JSON数据的方式提交,接收仍是bean形式
<script type="text/javascript" src="i/javascript/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#button").click(function(){
// json数据
var data = {id:$("#id").val(),name:$("#name").val()};
$.ajax({
type:"POST",
url:"${pageContext.request.contextPath}/submit.html",
data:data
});
});
});
</script>
接收使用bean,同3
@RequestMapping("/submit")
public String submit(Tag tag){
System.out.println(tag);
return "test";
}
二、多表单域接收方式
1. 方法参数数组方式
表单:
<form action="${pageContext.request.contextPath}/submit.html" method="POST">
<input type="text" name="id" />
<input type="text" name="name" />
<input type="text" name="id" />
<input type="text" name="name" />
<input type="submit" id="button" value="提交" />
</form>
接收:
@RequestMapping("/submit")
public String submit(String[] id, String[] name){
for(int i=0; i< id.length; i++){
System.out.println(id[i]);
System.out.println(name[i]);
}
return "test";
}
2. 用BeanList方式接收
表单:
<form action="${pageContext.request.contextPath}/submit.html" method="POST">
<input type="text" name="tags[0].id" />
<input type="text" name="tags[0].name" />
<input type="text" name="tags[1].id" />
<input type="text" name="tags[1].name" />
<input type="submit" id="button" value="提交" />
</form>
要准备一个Bean的List类:
import java.util.List;
public class TagList {
private List<Tag> tags;
public TagList(List<Tag> tags) {
this.tags = tags;
}
public TagList() {}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
}
接收:
@RequestMapping("/submit")
public String submit(TagList tags){
System.out.println(tags.getTags());
return "test";
}
三、接收参数时各种常见注解说明
@RequestBody
用在方法上,意义是会使用系统配置的HttpMessageConverter来对请求数据body部分进行解析。然后再把解析后的数据对象提供到方法参数上。
@RequestBody会根据Content-Type来分辨需要处理的内容:
- 常用于:application/json或application/xml等。
- 不能处理 multipart/form-data。
- 默认的application/x-www-form-urlencoded用不用@RequestBody没有关系。
@RequestParam
用于参数上,给参数标识绑定的提交值。比起Request.getParameter()会多做一步将值转换成简单类型。
其属性value指代参数域名称,而required指示是否必须传值,如果required=false则在不传值情况下给参数赋值null。
实际上在提交参数是简单类型的情况下可以忽略该注解,以下两段代码几乎的等同的:
@RequestMapping("/submit")
public String submit(
@RequestParam(value="id") int req_id,
@RequestParam(value="name") String req_name){
System.out.println(req_id);
System.out.println(req_name);
return "test";
}
@RequestMapping("/submit")
public String submit(String id, String name){
System.out.println(id);
System.out.println(name);
return "test";
}
如果用@RequestMapping注解的参数是int基本类型,但是required=false,这时如果不传参数值会报错(bad request (400)),因为不传值会赋值为null给int,这是不允许的。解决这个问题的方法是:用包装类型代替基本类型,如使用Integer代替int。
@ModelAttribute
如果用于Controller的方法上,那么通常是当此Controller的每个方法执行前执行,用于提前处理或者给request增加属性等。
如果用于方法的参数上面,有两种情况:
- 如果还有一个对应使用了@ModelAttribute注解的方法,或者是@SessionAttributes注解的SESSION值,那么这个参数会是该方法返回的对象。
- 如果没有对应的方法,那么就是从表单提交或者URL中获取数据对象,实际上不加@ModelAttribute注解效果也一样的。
@RequestMapping("/submit")
public String submit(@ModelAttribute Tag tag){
System.out.println(tag);
return "test";
}
@PathVariable
很方便取得URL的中的值,如:
@Controller
@RequestMapping("/test/{testId}")
public class TestController {
@RequestMapping("/method/{deepId}")
public void justdoit(@PathVariable String testId, @PathVariable String deepId) {
//...
}
}
@RequestHeader
取得请求头里面的某项信息:
@RequestMapping("/submit")
public String submit(@RequestHeader("User-Agent") String referer){
System.out.println(referer);
return "test";
}
@SessionAttributes
类级别的注解,作用是注明该Controller所使用的一个SESSION的key,该SESSION会在ModelMap参数里面保存,并且可以从里面使用。如果需要删除该SESSION值,那么得从参数里面传入SessionStatus并调用其setComplete方法。
@Controller
@SessionAttributes("testSession")
public class PostController extends BaseController {
@RequestMapping("/test")
public String index(ModelMap modelMap) {
modelMap.addAttribute("testSession", new Date());
return "test";
}
@RequestMapping("/submit")
public String submit(ModelMap modelMap, SessionStatus sessionStatus){
if(modelMap.containsAttribute("testSession")){
System.out.println(modelMap.get("testSession"));
sessionStatus.setComplete();
}
return "test";
}
}
@CookieValue
取特定cookie值
@RequestMapping("/submit")
public String submit(@CookieValue("JSESSIONID") String cookie){
System.out.println(cookie);
return "test";
}
以上是SpringMVC的提交参数获取方式,其实我们还可以直接通过Servlet的各种API来取得相同的数据;这里有个建议就是如果一个项目中使用了一种获取的模式,就一直用相同的方式,会更规范和容易理解。