学习SpringMVC的第二天
一、使用POJO对象绑定请求参数值
SpringMVC会按请求参数名和POJO属性名进行自动进行自动匹配,自动为该对象填充属性值。支持级联属性。如:dept.deptId、dept.address.tel等。
相关代码如下:
public class User {
private String username;
private String password;
private String email;
private int age;
private Address address;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + ", email=" + email + ", age=" + age
+ ", Address=" + address + "]";
}
}
public class Address {
private String province;
private String city;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address [province=" + province + ", city=" + city + "]";
}
}
<form action="springmvc/testPojo" method="post">
username:<input type="text" name="username"/>
<br>
password:<input type="password" name="password"/>
<br>
email:<input type="text" name="email"/>
<br>
age:<input type="text" name="age"/>
<br>
city:<input type="text" name="address.city"/>
<br>
province:<input type="text" name="address.province"/>
<br>
<input type="submit" value="submit"/>
<br>
</form>
@RequestMapping("/testPojo")
public String testPojo(User user) {
System.out.println("testPojo" + user);
return SUCCESS;
}
二、MVC的handle方法可以接受的ServletAPI类型的参数
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request,
HttpServletResponse response) {
System.out.println("testServletAPI" + request + "," + response);
return SUCCESS;
}
三、处理模型数据
1、ModelAndView:目标方法返回值类型可以为ModelAndView。其中可以包含视图和模型信息。SpringMVC会把ModeAndView的model中的数据放入到request域对象中。
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
String viewName = SUCCESS;
ModelAndView modelAndView = new ModelAndView(viewName);
//添加模型数据到ModelAndView中
modelAndView.addObject("time", new Date());
return modelAndView;
}
/**
*在success.jsp页面中添加
*/
time: ${requestScope.time }
2、Map及Model:入参为org.springframework.ui.Model、org.springframework.ui.ModelMap或org.uti.Map时,处理方法返回时,Map中的数据会自动添加到模型中。
@RequestMapping("/testMap")
public String testMap(Map<String,Object> map) {
map.put("names", Arrays.asList("Tom","Jerry","Mike"));
return SUCCESS;
}
//success.jsp
names: ${requestScope.names }
3、@SessionAttributes:将模型中的某个属性暂存到HTTPSession中,以便多个请求之间可以共享这个属性。
除了可以通过属性名指定需要放到回话中的属性外(实际上使用的是 value 属性值),
还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用的是types 属性值)
注意:只能放在类上面
/**
*在类上面添加@SessionAttributes({"user"})
*/
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes( Map<String,Object> map) {
User user = new User("Tom","123456","tom@qq.com",15);
map.put("user", user);
return SUCCESS;
}
//session.jsp
request user: ${requestScope.user }
<br>
session user: ${sessionScope.user }
4、@ModelAttribute:方法入参标注解后,入参的对象就会放到数据模型中。
1)有@ModelAttribute标记的方法,会在每个目标方法执行之前被SpringMVC调用
2)运行流程:
①执行@ModelAttribute 注解修饰的方法:从数据库中取出对象,把对象放到Map中。键为user
②执行SpringMVC从Map中取出User对象,并把表单的请求参数赋值给User对象的对应属性
③SpringMVC把上述对象传入目标方法的参数。
3)@ModelAttribute注解也可以来修饰目标方法POJO类型的入参,其value属性值有如下作用:
①SpringMVC会使用value属性值在implicitModel中查找对应的对象,若存在则会直接传入到目标方法的入参中
②SpringMVC会以value为key,POJO类型的对象为value,存入到request中
注意:在@ModelAttribute修饰的方法中,放入到Map时的键需要和目标方法入参类型的第一个字母小写的字符串一致
@ModelAttribute
public void getUser(@RequestParam(value="id" , required= false) Integer id , Map<String, Object> map) {
if(id != null) {
//模拟从数据库中获取对象
User user = new User("Tom","123456","tom@qq.com",12);
System.out.println("从数据库中获取一个对象:" + user);
map.put("user",user);
}
}
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user) {
System.out.println("修改:" + user);
return SUCCESS;
}
<!--
模拟修改操作
1.原始数据为:1,Tom,123456,tom@qq.com,12
2.密码不能被修改
3.表单回显,模拟操作直接在表单填写对应的属性值
-->
<form action="springmvc/testModelAttribute" method="Post">
<input type="text" name="id" value="1" /><br>
username:<input type="text" name="username" value="Tom" /><br>
email:<input type="text" name="email" value="tom@qq.com" /><br>
age:<input type="text" name="age" value="12" /><br>
<input type="submit" value="submit" />
</form>
总结
SpringMVC确定目标方法POJO类型入参的过程:
1、确定一个key
1)若目标方法的POJO类型的参数没有使用@ModelAttribute作为修饰,则key为POJO类名第一个小写
2)若使用了@ModelAttribute来修饰,则key为@ModelAttribute注解的value属性值
2、在implicitModel中查找key对应的对象,若存在,则作为入参传入
1)若在@ModelAttribute标记的方法中在Map中保存过,且key和1确定的key一致,则会获取到。
3、若implicitModel中不存在key对应的对象,则检查当前的Handler,是否使用@SessionAttributes注解修饰,若使用了该注解,且@SessionAttributes注解的value属性中包含key,则会从HttpSession中来获取key所对应的value值,若存在则直接传入到目标方法的入参中,若不存在这抛出异常。
4.若Handler没有标识@SessionAttributes注解或@SessionAttributes注解的value值不包含key,则会通过反射来创建POJO类型的参数,传入为目标方法的参数。
5、SpringMVC会把key和POJO类型的对象保存到implicitmodel中,进而会保存到request中。