一、什么是请求参数绑定
SpringMVC 绑定请求参数的过程是,通过表单将客户端请求的key=value数据传给controller,然后绑定到controller方法的形参,这样就可以在controller中使用该参数了。
二、请求参数数据类型
- 基本类型参数
包括基本类型和 String 类型
使用要求:参数名称必须和控制器中方法的形参名称保持一致。 (严格区分大小写)
- POJO 类型参数
包括实体类,以及关联的实体类
使用要求:表单中参数名称和 POJO 类的属性名称保持一致。并且控制器方法的参数类型是 POJO 类型。
- 数组和集合类型参数
包括 List 结构和 Map 结构的集合(包括数组)
使用要求:如果是集合类型,有两种方式
第一种:
要求集合类型的请求参数必须在 POJO 中。在表单中请求参数名称要和 POJO 中集合属性名称相同。
给 List 集合中的元素赋值, 使用下标。
给 Map 集合中的元素赋值, 使用键值对。
第二种:
接收的请求参数是 json 格式数据。需要借助一个注解实现。
注意:SpringMVC 绑定请求参数是自动实现的,但是要想使用,必须遵循使用要求。
三、使用举例
3.1 基本类型参数
index.jsp
<form action="${pageContext.request.contextPath}/user/testParam" method="post">
用户名: <input type="text" name="username"> <br>
年龄: <input type="text" name="age"> <br>
性别: <input type="text" name="sex"> <br>
<input type="submit" value="提交">
</form>
UserController.java
@Controller
@RequestMapping("/user")
public class UserController2 {
@RequestMapping(value = "/testParam",method = RequestMethod.POST)
public String testParam(String username,Integer age,Character sex){
System.out.println(username + "--" + age + "--" + sex);
return "show";
}
}
点击提交后:
请求格式为:
Request URL: http://localhost/user/testParam
Request Method: POST
Form Data:username=zhangsan&age=30&sex=男
后台结果:
3.2 POJO 类型参数
index.jsp
<form action="${pageContext.request.contextPath}/user/saveUser" method="post">
用户名: <input type="text" name="username"> <br>
年龄: <input type="text" name="age"> <br>
性别: <input type="text" name="sex"> <br>
一个角色对象:<!--role为 POJO类型参数-->
id:<input type="text" name="role.id">
roleName:<input type="text" name="role.roleName"><br>
<input type="submit" value="提交">
</form>
Role.java
public class Role {
private Integer id;
private String roleName;
//此处省略 getter and setter toString
}
User.java
public class User {
private Integer id;
private String username;
private Character sex;
private Integer age;
private Role role; //POJO 类型参数
//此处省略 getter and setter toString
}
UserController.java
@RequestMapping(value = "/saveUser",method = RequestMethod.POST)
public String saveUser(User user){
System.out.println(user);
return "show";
}
点击提交后:
请求格式为:
Request URL: http://localhost/user/saveUser
Request Method: POST
Form Data:username=zhangsan&age=30&sex=男&role.id=25&role.roleName=cook
后台结果:
3.3 POJO 类中包含集合类型参数
index.jsp
<form action="${pageContext.request.contextPath}/user/saveUser" method="post">
用户名: <input type="text" name="username"> <br>
年龄: <input type="text" name="ag"> <br>
性别: <input type="text" name="sex"> <br>
list集合参数: <input type="text" name="list[0]">
<input type="text" name="list[1]"><br>
一个角色对象:<input type="text" name="role.id">
<input type="text" name="role.roleName"><br>
多个角色对象:<input type="text" name="roleList[0].id">
<input type="text" name="roleList[0].roleName"><br>
<input type="text" name="roleList[1].id">
<input type="text" name="roleList[1].roleName"><br>
map集合:<input type="text" name="map[one]"><br>
<input type="text" name="map[two]"><br>
<input type="text" name="map[three]"><br>
<input type="submit" value="提交">
</form>
Role.java
public class Role {
private Integer id;
private String roleName;
//此处省略 getter and setter toString
}
User.java
public class User {
private Integer id;
private String username;
private Character sex;
private Integer age;
private List<String> list;
private Role role;
private List<Role> roleList;
private Map<String ,Object> map;
//此处省略 getter and setter toString
}
UserController.java
@RequestMapping(value = "/saveUser",method = RequestMethod.POST)
public String saveUser(User user){
System.out.println(user);
return "show";
}
点击提交后:
请求格式为:
Request URL: http://localhost/user/saveUser
Request Method: POST
Form Data:为方便展示,这里为解析后的格式
username: zhangsan
age: 30
sex: 男
list[0]: hello
list[1]: world
role.id: 21
role.roleName: cook
roleList[0].id: 23
roleList[0].roleName: teacher
roleList[1].id: 25
roleList[1].roleName: student
map[one]: little
map[two]: big
map[three]: huge
后台结果:为方便展示,这里为格式化后的
User {
id = null,
username = 'zhangsan',
sex = 男,
age = 30,
list = [hello, world],
role = Role {
id = 21,
roleName = 'cook'
},
roleList = [Role {
id = 23,
roleName = 'teacher'
}, Role {
id = 25,
roleName = 'student'
}
],
map = {
one = little,
three = huge,
two = big
}
}
四、RequestParam 注解实现参数绑定
把请求中指定名称的参数给控制器中的形参赋值。
属性:
- value: 请求参数中的名称。
- required:请求参数中是否必须提供此参数。默认值: true,表示必要参数,不提供则报错;false为非必要参数,不提供也没事。
举例:
index.jsp
<!--请求中未提供age参数-->
<a href="user/useRequestParam?name=test">requestParam 注解</a>
UserController.java
@RequestMapping("/useRequestParam")
public String useRequestParam(@RequestParam("name")String username,
@RequestParam(value="age",required=false)Integer age){
System.out.println(username+","+age);
return "show";
}
点击提交后:
请求格式为:
Request URL: http://localhost/user/useRequestParam?name=test
Request Method: GET
后台结果为:
五、自定义类型转换器
spring提供的类型转换接口
@FunctionalInterface
public interface Converter<S, T> {//S:表示接受的类型, T:表示目标类型
@Nullable
T convert(S source); //实现类型转换的方法
}
例1:控制器中的Date使用String类型接收
index.jsp
<form action="${pageContext.request.contextPath}/user/testDate">
<input type="date" name="birthday">
<input type="submit" value="提交">
</form>
UserController.java
@RequestMapping("/testDate")
public String testDate(String birthday){
System.out.println(birthday);
return "show";
}
点击提交后:
请求格式为:
Request URL: http://localhost/user/testDate?birthday=2019-08-02
Request Method: GET
后台结果为:
例2:控制器中的参数使用Date 类型接收
UserController.java
@RequestMapping("/testDate")
public String testDate(Date birthday){ //使用Date 类型接收
System.out.println(birthday);
return "show";
}
提交后报错:
解决办法
第一步:自定义String–>Date类型转换器
converter/StringToDateConverter.java
public class StringToDateConverter implements Converter<String ,Date>{
//把 String 类型转成日期类型
@Override
public Date convert(String source) {
//日期类型的转换对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = sdf.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
第二步:在 spring 配置文件中配置类型转换器。
spring 配置类型转换器的机制是,将自定义的转换器注册到类型转换服务中去。
spring-mvc.xml
<!-- 配置类型转换器工厂 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 给工厂注入一个新的类型转换器 -->
<property name="converters">
<set>
<!-- 配置自定义类型转换器 -->
<bean class="com.testfan.converter.StringToDateConverter"></bean>
</set>
</property>
</bean>
第三步:在 annotation-driven 标签中引用配置的类型转换服务
<!-- 引用自定义类型转换器 -->
<!--注解驱动: 关联类型转换工厂-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
再次测试
点击提交,后台可以正常打印日期
六、使用 ServletAPI 对象作为方法参数
SpringMVC 还支持使用原始 ServletAPI 对象作为控制器方法的参数。支持原始 ServletAPI 对象有:
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer
我们可以把上述对象,直接写在控制的方法参数中使用。
举例:
index.jsp
<a href="user/testServletAPI">测试访问 ServletAPI</a>
UserController.java
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request, HttpServletResponse response, HttpSession session){
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "show";
}
点击【测试访问 ServletAPI】,后台结果为: