在SpringMVC中处理模型数据的具体实现代码下载地址:http://download.csdn.net/download/bingbeichen/9793370。 SpringMVC主要提供了以下几种途径来处理模型数据,即:
ModelAndView:目标处理器中处理方法的返回值类型为ModelAndView时, 方法体即可通过该对象添加模型数据;Map及Model:入参为org.springframework.ui.Model、org.springframework.ui.ModelMap或java.uti.Map时,目标处理器中处理方法返回时,Map中的数据会自动添加到模型中;@SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享该属性;@ModelAttribute:目标处理器中处理方法的入参标注该注解后,入参的对象即会放到数据模型中。在目标处理器的处理方法中,若返回值为ModelAndView类型,则其既包含视图信息又包含模型数据信息。
@RequestMapping("/processModelData") @Controller public class ProcessModelData { private static final String SUCCESS = "success"; /** * 目标方法的返回值可以是ModelAndView类型,其可以包含视图和模型数据 * 原理:SpringMVC会将ModelAndView的model中的数据存放到request域对象中 * @return */ @RequestMapping("/testModelAndView") public ModelAndView testModelAndView() { ModelAndView modelAndView = new ModelAndView(SUCCESS); // 目标页面中可以直接用“${requestScope.time}”来获取所存放的模型数据 modelAndView.addObject("time", new Date()); return modelAndView; } }Spring MVC在内部使用org.springframework.ui.Model接口来存储模型数据。即Spring MVC在调用目标方法前会创建一个隐含的模型对象作为模型数据的存储容器;如果方法的入参为Map或Model类型,Spring MVC会将隐含模型的引用传递给该入参。因此,在方法体内,开发者即可以通过该入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。
@RequestMapping("/processModelData") @Controller public class ProcessModelData { private static final String SUCCESS = "success"; /** * 目标方法可以添加Map类型的参数,实际上也可以是Model或ModelMap类型 * @param map * @return */ @RequestMapping("/testMap") public String testMap(Map<String, Object> map) { System.out.println(map.getClass().getName()); // BindingAwareModelMap // 在目标页面可以通过“${requestScope.names}”的方式来访问模型数据 map.put("names", Arrays.asList("qiaobc", "qiaob", "qiaodb")); return SUCCESS; } }若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个@SessionAttributes注解, Spring MVC将把模型中对应的属性暂存到HttpSession中。
@SessionAttributes(value={"username"}, types={Date.class}) @RequestMapping("/processModelData") @Controller public class ProcessModelData { private static final String SUCCESS = "success"; /** * @SessionAttributes注解: * 1). 既可以通过属性名指定需要放到会话中的属性(实际上使用的是value属性值) * 2). 也可以通过属性类型指定要放到会话中的属性(实际上使用的是types属性值) * 3). 注意:该注解只可以标记在类上,而不能标记在方法上 * @param map * @return */ @RequestMapping("/testSessionAttributes") public String testSessionAttributes(Map<String, Object> map) { map.put("username", "whut-qiaobc"); map.put("birth", new Date()); return SUCCESS; } }在更新数据表记录且记录中存在不能修改的字段时,会先在目标方法中新建一个对应类的对象,表单会将修改后的字段值传递给该对象的指定属性,而不能修改字段的属性值却为空;此时,可在form表单中添加隐藏域(缺点:不便维护、可能泄露隐私)或从数据库中重新查找出该字段值。 在SpringMVC中即可先从数据库中获取模型数据,再根据表单参数修改获取的模型数据,进而进行更新操作,具体如下图所示:
注意:在使用SpringMVC进行数据绑定时,要主要目标控制器中处理方法的参数名与请求页面中的参数名相同,否则会出现“The request sent by the client was syntactically incorrect().”错误,其实质即是SpringMVC在进行参数绑定时出错。
根据运行流程分析可知,当标记类的注解@SessionAttributes(value={"user"}, types={Date.class})与目标方法public String testModelAttribute(User user){}相遇,且implicitModel中没有user对应的属性时,则SpringMVC会尝试从会话中获取user对应的属性,若获取失败则会抛出HttpSessionRequiredException异常。
