数据转发

操作 Map 系列参数

方法参数加上 Map<String,Object>ModelModelMap 三个中的任意一个即可,我们只要将数据保存到这些的参数实例中,Spring 会自动帮我们把数据放到 Request 域中。

关于这三个有什么关系呢:

300.jpg

其实 Spring 传入参数中的是 BindingAwareModelMap 实例,所以才能三个中任意一个作为参数都能实现数据的转发。

@ModelAttribute

这里需要重点说一下用来处理隐含数据模型 bindingAwareModelMap 的注解 @ModelAttribute,此注解可被应用在方法或方法参数上。

方法注释

@ModelAttribute 标注到一个方法上面的时候,就意味着这个方法为数据模型处理方法,这个方法是用来在隐藏数据模型添加一些数据的。所以被这个注解标注的方法会在当前类下面的任意一个请求映射方法被调用之前运行

@ModelAttribute 标注方法有两种风格:

  • 在第一种写法中,方法通过返回值的方式默认地将添加一个属性;
1
2
3
4
@ModelAttribute("Xorex")
public User addUser() {
return new User("XXX","XXX",324234);
}

这里将返回的 User 对象添加到隐藏数据模型中,key 为我们在注解中设置的 Xorex,如果不设置,那么默认为添加的数据类型 User 的首字母小写 user。

  • 在第二种写法中,方法接收一个 Model 对象,然后可以向其中添加任意数量的属性。
1
2
3
4
@ModelAttribute
public void addUser(Model model) {
model.addAtribute("Xorex",new User());
}

参数注释

标注在方法参数上的 @ModelAttribute 说明了该方法参数的值将由 model 中取得。如果 model 中找不到,那么该参数会先被实例化,然后被添加到 model 中。在 model 中存在以后,请求中所有名称匹配的参数都会填充到该参数中。

就是用来从隐含数据模型中取数据用的。

1
2
3
4
5
@RequestMapping("/XXX/XXX")
public String addUser(@ModelAttribute("Xorex") User user) {
System.out.println(user);
return "XXX/XXX";
}

而参数 user 可能来自于:

  1. 因为 @SessionAttributes 标注的使用已经存在于 model 中
  2. 它可能因为在同个控制器中使用了 @ModelAttribute 方法已经存在于 model 中,正如上面所叙述的将注解标注到方法上面。
  3. 它可能是调用了自身的默认构造器被实例化出来的,在 model 中找不到实例,只能创建。

使用 ModelAndView

ModelAndView 模型(页面需要用到的数据)和视图(数据的展示),这个东西会同时起到两个作用,那就是 request 域数据的保存和页面的转发:

1
2
3
4
5
6
@RequestMapping("/Test/")
public ModelAndView test() {
ModelAndView mv = new ModelAndView("hello"); //确认转发的 View 层地址
mv.addObject("Tempest", "Xorex"); //向 request 域中写数据
return mv;
}

设置 ModelAndView 作为方法返回对象,设置实例的转发 View 页面,设置 Model 数据。

Session 中的数据

这里推荐还是使用原生的 API HttpSession 进行存取数据,更加方便安全。

而 SpringMVC 提供了两种和 Session 进行数据交互的注解,为标注在类上面的注解 @SessionAttributes 和标注在参数上面的注解 @SessionAttribute

对于 @SessionAttributes:是用于在请求之间的 HTTP Servlet 会话中存储 model 属性。其 Value 用来填写放入 Session 中的 Key,然后 Spring 会在隐含数据模型中寻找相同的 Key,并把里面的值复制一份放入 Session 中。也就是说 Session 有的,隐含数据域中也必须有。而注解的另外一个参数则是 Types,这个不是去隐含数据模型中寻找 Key 了,而是值的类型,将符合 Types 类型的数据放入 Session 中。这个很危险,不建议使用。

而且一旦在隐含数据模型中找不到指定的数据,那么 @SessionAttributes 注解就会报错。


然后就是从 Session 中获取数据了,使用的是 @SessionAttribute

需要将 @SessionAttribute("XXX") 就可以将 Session 中保存的 key 为 XXX 的数据放入被标注的方法参数中。

1
2
3
4
5
@RequestMapping("/XXX/XXX")
public String addUser(@SessionAttribute("Xorex") User user) { // 从 Session 中取出 key 为 Xorex 的值。
System.out.println(user);
return "XXX/XXX";
}