springmvc(五)之处理模型数据

1. 模型数据

springmvc 提供了以下几种途径输出模型数据:

  • ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据
  • Map及Model:入参为Model、ModelMap、Map,处理方法返回时,Map中的数据会自动添加到模型数据中
  • @SessionAttribute:将模型数据暂存到HttpSession中,以便多个请求之间可以共享这个属性
  • @ModelAttribute:方法入参标注该注解后,入参的对象就会放到数据模型中

1.1ModelAndView

  • 控制器处理方法的返回值如果为ModelAndView,则其既包含视图信息,也包含模型数据信息
  • 添加模型数据
    ModelAndView addObject(String attributeName, Object attributeValue)
    ModelAndView addAllObject(Map<String, ?> modelMap)
  • 设置视图
    void setView(View view)
    void setViewName(String viewName)

后台:
使用构造方法添加视图

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
	String viewName = SUCCESS;
	// 1.设置视图(通过构造器)
	ModelAndView modelAndView = new ModelAndView(viewName);
	// 2.添加模型数据
	modelAndView.addObject("time", new Date());
	return modelAndView;
}

或者使用setter()方法添加视图

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
	String viewName = SUCCESS;
	ModelAndView modelAndView = new ModelAndView();
	// 1.添加模型数据
	modelAndView.addObject("time", new Date());
	//2.使用setter()方法添加视图
	modelAndView.setViewName(viewName);
	return modelAndView;
}

springmvc会把ModelAndView的model中数据放入到request域中

前端访问:

<a href="test/testModelAndView">testModelAndView</a>

跳转页面success.jsp

<body>
	<h1>SUCCESS</h1>
	
	${time}
</body>

获取了之前添加的数据模型time的值
在这里插入图片描述

1.2Map及Model

  • springmvc在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器
  • 如果方法的入参为Map/Model类型,springmvc会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的素有数据,也可以向模型中添加新的属性数据

后台
使用Map

@RequestMapping("/testMap")
public String testMap(Map<String, Object> map) {
	map.put("names", Arrays.asList("Tom", "Andy"));
	return SUCCESS;
}

往Map中添加了一个key为names,值为:{tom, andy}

或者使用Model

@RequestMapping("/testMap")
public String testMap(Model model) {
	model.addAttribute("names", Arrays.asList("Tom", "Andy"));
	return SUCCESS;
}

前端访问

<a href="test/testMap">testMap</a><br>

success.jsp页面获取map

<body>
	<h1>SUCCESS</h1>
	
	${names }
</body>

在这里插入图片描述

1.3@SessionAttribute(标注在类上)

  • @SessionAttribute除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
    @SessionAttribute(type=User.class):会将隐含模型中类型为User.class的属性添加到会话中
    @SessionAttribute(type={User.class, Emp.class}):
    @SessionAttribute(value={“user1”, “user2”})
    @SessionAttribute(value={“user1”, “user2”}, type=Emp.class)
@Controller
@RequestMapping("/test")
@SessionAttributes(value="user")
public class TestController {
	private static final String SUCCESS = "success";
	
	@RequestMapping("/testSession")
	public String testSession() {
		User user = new User();
		return SUCCESS;
	}
	...
}

则user被放在session域中

1.4@ModelAttribute

应用场景:当我们修改数据时,用form表单提交,后台用相应的POJO接收,但我们想让其中一个字段不变,如:密码password。我们一旦用POJO接收后,如果传过来的字段没有password,则会自动为此POJO对象的属性password赋值为null。但我们只是想要它不变。所以,我们需要用先从数据库获取此对象属性对应的数据

前端form表单

<form action="test/testModelAttribute" method="post">
		<input type="hidden" name="id" value="1" />
		UserName:<input type="text" name="username" value="zzc" />
		Province:<input type="text" name="address.province" value="Hubei" />
		City:<input type="text" name="address.city" value="WuHan" />
		<input type="submit" value="提交" />
</form>

原始数据:
name:zzc
password:123456
province:Hubei
city:WuHan

后台:

@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user) {
	System.out.println(user);
	return SUCCESS;
}

打印结果发现:
password==null,这不是我们想要的结果

修改:

	// 1.模拟从数据库中获取数据
	@ModelAttribute
	public void getUser(@RequestParam(value="id", required=false) Integer id, 
			Map<String, Object> map) {
		if(null != id) {
			User u = new User();
			u.setUsername("zzc");
			u.setPassword("123456");
			Address address = new Address();
			address.setProvince("Hubei");
			address.setCity("WuHan");
			u.setAddress(address);
			
			map.put("user", u);
		}
	}
	
	@RequestMapping("/testModelAttribute")
	public String testModelAttribute(User user) {
		System.out.println(user);
		return SUCCESS;
	}

在getUser()方法上添加@ModelAttribute注解。然后就能达到预期的要求了

有@ModelAttribute标记的方法,会在每个目标方法执行之前被springmvc调用

运行流程:

  1. 执行@ModelAttribute注解修饰的方法 :从数据库取出数据;把对象放入map中,其中k=user
  2. springmvc从map中取出User对象,并把表单请求参数赋值给user对象的对应属性
  3. springmvc把上述对象传入目标方法的参数

【注意】:在@ModelAttribute注解修饰的方法中,放入到map时的key需要和目标方法入参类型的第一个字母小写的字符串一致。若不一致,则password还是为null。解决方案是用@ModelAttribute注解

@ModelAttribute标记修饰目标方法POJO类型的入参

	@ModelAttribute
	public void getUser(@RequestParam(value="id", required=false) Integer id, 
			Map<String, Object> map) {
		if(null != id) {
			User u = new User();
			...
			
			map.put("u", u);
		}
	}
	
	@RequestMapping("/testModelAttribute")
	public String testModelAttribute(@ModelAttribute("u") User user) {
		System.out.println(user);
		return SUCCESS;
	}
发布了78 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Lucky_Boy_Luck/article/details/100064260