SpringMVC第二弹。
SpringMVC-2-参数绑定与常用注解
1. 参数绑定
表单中的请求参数都是基于键值对的。SpringMVC绑定请求参数的过程是:把表单的请求参数作为控制器中方法的参数进行绑定。
SpingMVC请求参数的绑定是自动实现的,但要遵守规范。
1. 基本类型参数绑定
包含了基本数据类型和String类型
规范:参数名称必须和控制器方法参数一致,且严格区分大小写。
1 | <a href="params/getUsername?username=tobing">测试普通数据类型绑定</a> |
1 |
|
2. POJO类型参数绑定
包含了自定义实体类,以及其中关联的实体类
规范:参数名称必须和实体类属性名称一致,且控制器方法参数就是实体类。
1 | 测试JavaBean类型绑定 |
1 | // JavaBean |
3. 数组和集合类型参数绑定
包括了List结构和Map结构
规范:集合类型请求参数必须在实体类中,且请求参数名称要和实体类的属性名称一致。
List:使用下标
Map:使用键值对
1 | 参数绑定map和list |
1 | // Javabean |
4. 自定义类型转换器
当我们输入的数据格式不符合自动参数绑定的规范的时候,SpringMVC并不能帮助我们封装参数,会出错。(例如:2019/01/01可以自动封装Date,而2019-01-01会报400错误)
此时除了更改数据格式,还可以使用自定义类型转换器,把数据封装。
自定义类型转换器实际是我们把获取到的数据进行自定义封装。
使用步骤一:定义实现了Converter接口的实体类
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class StringtoDateConverter implements Converter<String, Date> {
public Date convert(String source) {
if(source==null){
throw new RuntimeException("没找到数据");
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(source);
} catch (ParseException e) {
throw new RuntimeException("日期格式异常!");
}
}
}以上类实现了将yyyy-MM-dd格式的字符串转换为Date类型
在Spring配置文件中配置类型转换器
spring 配置类型转换器的机制是,将自定义的转换器注册到类型转换服务中去。
1
2
3
4
5
6
7
8
9
10
11
12
13<!--配置转换器-->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<!--添加自己实现的转换器-->
<bean class="top.tobing.utils.StringtoDateConverter"></bean>
</set>
</property>
</bean>
<!--配置spring开启mvc注解-->
<!--引用转换器-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>
5. 使用ServletAPI对象作为方法参数
SpringMVC 支持使用原始 ServletAPI 对象作为控制器方法的参数。
支持的对象有:HttpServletRequest、HttpServletResponse 、HttpSession、 java.security.Principal 、Locale、InputStream 、OutputStream、 Reader、 Writer
使用是直接将对象定义在控制器方法参数中
1 | <a href="params/getServletAPI" >获取Servlet原生API</a> |
1 |
|
2. 常用注解
1. RequestParam
作用:参数绑定时,把不符合规范的参数绑定到控制器方法指定的参数
属性:
value:请求参数的名称
required:请求参数中是否必须提供此参数。默认值:true。(表示必须提供,如果不提供将报错。 )
使用
1
2<a href="annos/testRequestParam?name=tobing">testRequestParam</a><br>
1
2
3
4
5
6
7
8
9
10
11
12
public class AnnoController {
public String testRequestParam( String usernmae){
System.out.println("testRequestParam执行了");
System.out.println(usernmae);
return "success";
}
}将请求参数name绑定到控制器方法username参数上
2. RequestBody
作用:用于获取请求体内容( key=value&key=value…结构的数据),get 请求方式不适用。
属性:
required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值 为 false,get 请求得到是 null。
使用:
1
2<a href="annos/testRequestBody">testRequestBody</a><br>
1
2
3
4
5
6
7
public String testRequestBody( String body){
System.out.println("testRequestBody执行了");
System.out.println(body);
return "success";
}
3. PathVaribale
作用:绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。 url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。
属性:
value:用于指定url中占位符名称
required:是否必须提供占位符
使用:
1
2<a href="annos/testPathVariable/1024">testPathVariable</a><br>
1
2
3
4
5
6
7
public String testPathVariable( String id){
System.out.println("testPathVariable执行了");
System.out.println(id);
return "success";
}
4. RequestHeader(少用)
作用:获取请求头
属性:
value:要获取的消息头名称
required:是否必须有次消息头
使用:
1
2<a href="annos/testRequestHeader">testRequestHeader</a><br>
1
2
3
4
5
6
7
public String testRequestHeader( String header){
System.out.println("testRequestHeader执行了");
System.out.println(header);
return "success";
}
获取请求头中的Accept消息
5. CookieValue
作用:把指定cookie传到控制器方法参数中
属性:
value:指定 cookie 的名称。
required:是否必须有此 cookie。
使用:
1
2<a href="annos/testCookieValue">testCookieValue</a><br>
1
2
3
4
5
6
7
8
public String testCookieValue( String cookie){
System.out.println("testCookieValue执行了");
System.out.println(cookie);
return "success";
}
6. ModeAttribute
作用:
可以用于修饰方法和参数。
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可 以修饰有具体返回值的方法。
出现在参数上,获取指定的数据给参数赋值。
属性:
value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key
使用场景
当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
例如:我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数 据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题。
使用:
1
2<a href="annos/testModelAttribute?username=tobing">testModelAttribute</a><br>
修饰在方法上
1
2
3
4
5
6
7
8
9
10
11
public String testModelAttribute(User user){
System.out.println("testModelAttribut执行了"+user.getUsername());
return "success";
}
public void showModelAttribute(User user){
System.out.println("showModelAttribut执行了"+user.getUsername());
}
showModelAttribut会先执行
修饰在参数上:给指定参数赋值(方式一)
1
2
3
4
5
6<form method="post" action="annos/testModelAttribute">
用户名:<input type="text" name="username"/><br>
密码:<input type="text" name="password"/><br>
<input type="submit" value="提交">
</form>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public User showModel(String username,String password){
User user = new User();
user.setUsername(username);
user.setPassword(password);
user.setBirthday(new Date());
System.out.println("showModel执行了"+user);
return user;
}
public String testModelAttribute(User user){
System.out.println("testModelAttribut执行了"+user);
return "success";
}
修饰在参数上:给指定参数赋值(方式二)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void showModel(String username, Map<String,User> map){
User user = new User();
user.setUsername(username);
user.setPassword("root");
user.setBirthday(new Date());
map.put("u",user);
}
public String testModelAttribute( User user){
System.out.println("testModelAttribut执行了"+user);
return "success";
}
7. SessionAttribute
作用:用于多次执行控制器方法间的参数共享。
属性:
value:用于指定存入的属性名称
type:用于指定存入的数据类型。
使用:
1
2
3
4<a href="annos/testPut">存入SessionAttribute</a><br>
<a href="annos/testGet">取出SessionAttribute</a><br>
<a href="annos/complete">删除SessionAttribute</a><br>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// 存入session
public String testPut(Model model){
model.addAttribute("username","tobing");
model.addAttribute("password","root");
model.addAttribute("age",21);
return "success";
}
// 取出session
public String testGet(ModelMap model){
System.out.println(""+model.get("username")+model.get("password")+model.get("age"));
return "success";
}
// 删除session
public String complete(SessionStatus status){
status.setComplete();
return "success";
}