SpringMVC处理模型数据及SpringMVC 确定目标方法 POJO 类型入参的过程

来源:互联网 发布:sql合并相同行并合计 编辑:程序博客网 时间:2024/06/05 07:31

Spring MVC 提供了以下几种途径输出模型数据:可以在目标页面输出想要的数据

1.  将模型数据放入request域对象中的两种方式。

 ① ModelAndView:

  处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据;其中可以包含视图和模型信息;SpringMVC 会把 ModelAndView 的 model    中的数据放入       到 request 域对象中,在jsp界面可用${requestScope.参数名}来访问显示的数据。如:${requestScope.time}。
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
String viewName = SUCCESS;
ModelAndView modelAndView = new ModelAndView(viewName);
//添加模型数据到 ModelAndView 中.
modelAndView.addObject("time", new Date());
return modelAndView;
}
 ② Map 及 Model:

  入参为org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。
    jsp界面使用:${requestScope.names}来得到数据。
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
System.out.println(map.getClass().getName());
map.put("names", Arrays.asList("Tom", "Jerry", "Mike"));
return SUCCESS;
}

2.  将模型数据放入session域对象中的方法。
  ① @SessionAttributes

 将模型中的某个属性暂存到HttpSession 中,以便多个请求之间可以共享这个属性。若希望在多个请求之间共用某个模型属性数据,则可以在 控制器类上标注一个              @SessionAttributes。若不写这个注解,那么就会保存在request中,写了后这两种方式都可以调用。

注意: 该注解只能放在类的上面. 而不能修饰放方法.

      /* @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(实际上使用的是 value 属性值), 

        * 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用的是 types 属性值)

        * 注意: 该注解只能放在类的上面. 而不能修饰放方法.

        * jsp中user对象和school都可以获得了,因为使用了(values={“user”}, types={String.class}

        */

       @SessionAttributes(values={“user”}, types={String.class})

       @RequestMapping("/testSessionAttributes")

       publicString testSessionAttributes(Map<String, Object> map){

              Useruser = new User("Tom", "123456","tom@atguigu.com", 15);

              map.put("user",user);

              map.put("school","atguigu");

              return SUCCESS;

       }

2. @ModelAttribute 

方法入参标注该注解后, 入参的对象就会放到数据模型中。有@ModelAttribute标记的方法, 会在每个目标方法执行之前被 SpringMVC 调用!

如果想要某一个属性的部分字段,方法:hidden(如果是密码 或者 有很多字段,那就不合适了),使用@ModelAttribute,将这个属性从数据库中取出,然后更新这个属     性的部分字段(不是new,不然没有更新的字段也会是null)。
@ModelAttribute
public void getUser(@RequestParam(value="id",required=false) Integer id, Map<String, Object> map){
System.out.println("modelAttribute method");
if(id != null){
//模拟从数据库中获取对象
User user = new User(1, "Tom", "123456", "tom@atguigu.com", 12);
System.out.println("从数据库中获取一个对象: " + user);
map.put("user", user); //取出数据并存于map中
}
}
//再取出这个数据即可
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println("修改: " + user);
return SUCCESS;
}
3.  @ModelAttribute运行流程:

①执行 @ModelAttribute 注解修饰的方法: 从数据库中取出对象, 把对象放入到了 Map 中. 键为: user

② SpringMVC 从 Map 中取出 User 对象, 并把表单的请求参数赋给该 User 对象的对应属性.

③ SpringMVC 把上述对象传入目标方法的参数.

注意: 在 @ModelAttribute 修饰的方法中, 放入到 Map 时的键需要和目标方法入参类型的第一个字母小写的字符串一致。如map.put("user",user); 的key必须为user。如果key为abc,那么可以在方法中使用 @ModelAttribute(key)这个方法来实现一致:

public String testModelAttribute(@ModelAttribute(“abc”) User user){

4.  SpringMVC 确定目标方法 POJO 类型入参的过程

    ①. 确定一个 key:

       1).若目标方法的 POJO 类型的参数木有使用 @ModelAttribute 作为修饰, 则 key 为 POJO 类名第一个字母的小写

       2).若使用了@ModelAttribute来修饰, 则 key 为 @ModelAttribute 注解的 value 属性值.

    ②. 在 implicitModel 中查找 key 对应的对象, 若存在, 则作为入参传入

       1).若在 @ModelAttribute标记的方法中在 Map 中保存过, 且 key 和步骤 1 确定的 key 一致, 则会获取到.

    ③. 若 implicitModel 中不存在 key 对应的对象, 则检查当前的 Handler 是否使用 @SessionAttributes 注解修饰, 若使用了该注解, 且@SessionAttributes 注解的 value 属性值中包含了 key, 则会从HttpSession 中来获取 key 所对应的 value 值, 若存在则直接传入到目标方法的入参中. 若不存在则将抛出异常.

    ④. 若 Handler 没有标识 @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key, 则会通过反射来创建 POJO类型的参数, 传入为目标方法的参数

    ⑤. SpringMVC 会把 key 和 POJO 类型的对象保存到 implicitModel 中, 进而会保存到 request 中.

注:

   @ModelAttribute 注解也可以来修饰目标方法 POJO 类型的入参, 其 value 属性值有如下的作用:

1). SpringMVC 会使用 value 属性值在 implicitModel 中查找对应的对象, 若存在则会直接传入到目标方法的入参中.

2).SpringMVC 会把 value 为 key, POJO 类型的对象为 value, 存入到 request 中.5. @SessionAttribute注解引起的异常

@SessionAttribute注解引发的异常:找不到session中的user

  原因:若 implicitModel 中不存在 key 对应的对象, 则检查当前的 Handler 是否使用 @SessionAttributes 注解修饰, 若使用了该注解, 且@SessionAttributes 注解的 value 属   性值中包含了 key, 则会从HttpSession 中来获取 key 所对应的 value 值, 若存在则直接传入到目标方法的入参中. 若不存在则将抛出异常。

解决方法:加@ModelAttribute,因为如果没有这个注解,那么就会默认去找   public String testModelAttribute(User user) 中的user,当然也可以使     @ModelAttribute(value=”abc”)来使两个的user不一致,这样也能解决异常。


原创粉丝点击