SpringMVC参数绑定

参数绑定

数据绑定是一个自动转换及赋值的过程,它负责将 HTTP 请求中的 String 类型的参数,转换为其他类型的请求处理方法的参数。

1. 绑定简单类型

当 HTTP 请求的参数名和处理方法参名一致时,SpringMVC 会将请求参数与形参进行绑定。

参数类型强烈建议使用 包装类

如果没有那么『凑巧』,HTTP 请求参数名和方法形参名不一致,可通过 @RequestParam 注解进行手动指定。

属性 作用
value 指定 request 中参数的名称。
required 指定是否必须,是否必须,默认是 true。必须意味着为空时,报错退出。
defaultValue 默认值,表示如果请求中没有同名参数时的默认值。
java 复制代码
public String login1(
    @RequestParam String username,
    @RequestParam(value = "password", required = false, defaultValue = "N/A") String password) {
  ...
  ...
  ...
}

2. 绑定到 JavaBean

JavaBean 对象中的属性名和表单中 <input>name 属性一致,并且 Controller 方法以 JavaBean 为形参即可。

HTML 表单
html 复制代码
<p><input name="name" placeholder="学生姓名" value="jerry"></p>
<p><input name="age" placeholder="学生年龄" value="19"></p>
<p>
   <label><input type="radio" name="male" value="true" checked> 男</label>
   <label><input type="radio" name="male" value="false">女</label>
</p>
<p><button type="submit">提交</button></p>
表单对象
java 复制代码
public class Student {
    private String name;
    private Integer age;
    private Boolean male;
    ...
}
使用
java 复制代码
// 注意,这里没有 @RequestParam 注解
public String login(Student student) {
    ...
}

3. 绑定到数组

如果页面上使用了 <input type ="checkbox"> 那么,HTTP 提交到后台的将是一个数组。这里有 2 种绑定方式。

HTML 表单
html 复制代码
<p><input type="checkbox" name="likes" value="足球">足球</p>
<p><input type="checkbox" name="likes" value="篮球">篮球</p>
<p><input type="checkbox" name="likes" value="乒乓球">乒乓球</p>
<p><input type="checkbox" name="likes" value="游泳">游泳</p>
<p><input type="checkbox" name="likes" value="跑步">跑步</p>
表单对象
java 复制代码
public class Student {

    private String[] likes;

    ...
}
使用
java 复制代码
// 注意,这里没有 @RequestParam 注解
public ModelAndView register(Student student) {

}
其它

另外,如果不定义、不使用表单对象,而是直接绑定到 Controller 方法的数组型参数中也可以如下述形式直接使用 @RequestParam 注解:

java 复制代码
public ModelAndView register(..., @RequestParam String[] likes)

简而言之,数组既可以做方法的参数对象本身,又可以做参数对象的属性。这里有 2 种绑定方式。

4. 不常见绑定

4.1 绑定到复合 JavaBean

需要将表单中的数据绑定到一个对象中的某个对象属性上。例如:FormVO 对象下的 Student 属性。

这种情况下,需要页面 <input> 元素的 name<属性名>.<属性名>

HTML 表单
html 复制代码
<p><input name="name" placeholder="老师姓名" value="tom"/></p>
<p><input name="age" placeholder="老师年龄" value="40"/></p>
<p><input name="student.name" placeholder="学生姓名" value="jerry"/></p>
<p><input name="student.age" placeholder="学生年龄" value="19"/></p>
<p><input type="submit" value="提交"/></p>
表单对象
java 复制代码
public class Student {
    private String name;
    private Integer age;
    ...
}

public class Teacher {
    private String name;
    private Integer age;
    private Student student; /* name, age */
    ...
}
使用
java 复制代码
// 注意,这里没有 @RequestParam 注解
public String demo(Student student) {
    ...
}

4.2 绑定到 List

和数组不同,List 只能作方法的参数对象的属性,而不能做参数对象本身。这里只有 1 种绑定方式。

HTML 表单
html 复制代码
<p><input name="name" placeholder="老师姓名" value="tom"/></p>
<p><input name="age"  placeholder="老师年龄" value="40"/></p>
<p><input name="students[0].name" placeholder="学生1姓名" value="jerry"/></p>
<p><input name="students[0].age"  placeholder="学生1年龄" value="20"/></p>
<p><input name="students[1].name" placeholder="学生2姓名" value="lucy"/></p>
<p><input name="students[1].age"  placeholder="学生2年龄" value="19"/></p>
<p><input name="students[2].name" placeholder="学生3姓名" value="lily"/></p>
<p><input name="students[2].age"  placeholder="学生3年龄" value="19"/></p>
<p><input type="submit" value="提交"/></p>
表单对象
java 复制代码
public class Teacher {
    private String name;
    private String age;
    private List<Student> students;
  ...
}
使用
java 复制代码
// 注意,这里没有 @RequestParam 注解
public ModelAndView register(Teacher student) {
}

4.3 绑定到 Set

Set 和 List 类似,它只能作方法的参数对象的属性,而不能做参数对象本身。即,只有 1 中绑定方式。

另外,作为属性的 Set 必须提前初始化,且其中有相对应的模型对象。

HTML 表单
html 复制代码
<p><input name="name" placeholder="老师姓名" value="tom"/></p>
<p><input name="age"  placeholder="老师年龄" value="40"/></p>
<p><input name="students[0].name" placeholder="学生1姓名" value="jerry"/></p>
<p><input name="students[0].age"  placeholder="学生1年龄" value="20"/></p>
<p><input name="students[1].name" placeholder="学生2姓名" value="lucy"/></p>
<p><input name="students[1].age"  placeholder="学生2年龄" value="19"/></p>
<p><input name="students[2].name" placeholder="学生3姓名" value="lily"/></p>
<p><input name="students[2].age"  placeholder="学生3年龄" value="19"/></p>
<p><input type="submit" value="提交"/></p>
表单对象
java 复制代码
public class Teacher {

    private String name;
    private String age;
    private Set<Student> students;

    public Teacher() {
        set = new HashSet<>();  // 这是不同于 List(和 Map)的地方。
        set.add(new Student()); // 注意这里的 hashCode 问题,挺有意思的。
        set.add(new Student());
        set.add(new Student());
    }
    ...
}
使用
java 复制代码
public ModelAndView register(Teacher student) {
}

4.4 绑定到 Map

Map 和 Set、List 类似,它只能作方法的参数对象的属性,而不能做参数对象本身。即,只有 1 种绑定方式。

HTML 表单
html 复制代码
<p><input name="name" placeholder="老师姓名" value="tom"/></p>
<p><input name="age"  placeholder="老师年龄" value="40"/></p>
<p><input name="students['xxx'].name" placeholder="学生1姓名" value="jerry"/></p>
<p><input name="students['xxx'].age"  placeholder="学生1年龄" value="20"/></p>
<p><input name="students['yyy'].name" placeholder="学生2姓名" value="lucy"/></p>
<p><input name="students['yyy'].age"  placeholder="学生2年龄" value="19"/></p>
<p><input name="students['zzz'].name" placeholder="学生3姓名" value="lily"/></p>
<p><input name="students['zzz'].age"  placeholder="学生3年龄" value="19"/></p>
<p><input type="submit" value="提交"/></p>
表单对象
java 复制代码
public class Teacher {
    private String name;
    private Integer age;
    private Map<String, Student> students;
    ...
}
使用
java 复制代码
// 注意,这里没有 @RequestParam 注解
public ModelAndView register(Teacher student) {

  for (Map.Entry entry : teacher.getStudents().entrySet()) {
    log.info("{}, {}", entry.getKey(), entry.getValue());
  }

}

5. @DateTimeFormat 和 @NumberFormat

有时会从前台向后台传入日期格式字符串,例如:

html 复制代码
<p><input type="text" name="birthday" value="2000-10-1" placeholder="学生生日"></p>

一般情况下,不至于用到(后面所说的自定义类型转换),Spring MVC 提供了现成的 @DateTimeFormat 注解来解决 StringDate 的转换。

java 复制代码
public Student {

    ...

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;

    ...
}

注意,@DateTimeFormat 是用于 FO 上的,而非 VO、DTO 。

另外,对于有特定格式的字符串,也有类似的注解:@NumberFormat 可用。

java 复制代码
@NumberFormat("###,#####")
public double price;
相关推荐
军军君011 小时前
基于Springboot+UniApp+Ai实现模拟面试小工具二:后端项目搭建
前端·javascript·spring boot·spring·微信小程序·前端框架·集成学习
Linn5 小时前
Spring WebSocket 服务实现的主流方案与最佳实践
spring boot·后端·spring
NE_STOP5 小时前
SpringBoot--如何整体读取多个配置属性及其相关操作
java·spring
二饭8 小时前
解决Maven“无法将类 XXXXX 中的构造器 XXXXXX 应用到给定类型”错误
java·spring·maven
努力的小郑8 小时前
Spring监听器(ApplicationEvent):比MQ更轻的异步神器!亿级流量下的咖啡店经营哲学
java·后端·spring
Cyanto18 小时前
Spring注解IoC与JUnit整合实战
java·开发语言·spring·mybatis
qq_4338889318 小时前
Junit多线程的坑
java·spring·junit
gadiaola18 小时前
【SSM面试篇】Spring、SpringMVC、SpringBoot、Mybatis高频八股汇总
java·spring boot·spring·面试·mybatis
写不出来就跑路18 小时前
WebClient与HTTPInterface远程调用对比
java·开发语言·后端·spring·springboot
麦兜*19 小时前
Spring Boot 集成Reactive Web 性能优化全栈技术方案,包含底层原理、压测方法论、参数调优
java·前端·spring boot·spring·spring cloud·性能优化·maven