21.13.2 ModelMap模型(ModelAndView)
ModelMap类,主要是一个Map,用来在一个包含着常见命名转换的View上进行展示的对象。请看下面关于Controller实现的例子,特别注意,对象被直接添加到了ModelAndView中,且并没有指定任何关联的名称。
public classDisplayShoppingCartController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponseresponse) {
List cartItems = // 获取CartItem的List对象
User user = // 获取正在购物的User对象。
ModelAndView mav = new ModelAndView("displayShoppingCart"); <-- 逻辑视图名
mav.addObject(cartItems); <--看这里,根本没有名字,只有一个对象。
mav.addObject(user); <-- 又来了!
return mav;
}
}
ModelAndView类使用了一个实现了自定义Map的ModelMap类,它会在添加时自动地生成对象的键名。生成名字的方法是:如果是类似User这样的标准对象,会用这个对象类的短类名作为它的名字。下面的例子就是在ModelMap中自动为标准对象生成的名字。
- 一个x.y.User的实例,添加时会命名为user
- 一个x.y.Registration实例,添加时会命名为registration
- 一个x.y.Foo实例,添加时会命名为foo
- 一个java.util.HashMap实例,添加时会命名为hashMap
如果添加null,会抛出IllegalArgumentException异常。如果你添加的对象有可能是null,你也需要显式地指定其名。
什么?居然没有自动多元?
Spring Web MVC的“约定优先于配置”不支持自动多元。意思是,你不能通过添加一个List<Person>的对象到ModelAndView中,并生成其名为”people”。
这个决定我们争论许久,最后还是“风险最小原则”赢了。
当添加一个Set或者List对象的命名生成方法是:把这些对象在集合中置顶,取集合中第一个对象的短类名,然后在名字后面加上“List”。这个规则对数组也同样适用。下面是一些例子:
- 一个x.y.User[]数组,包含了0个或多个x.y.User对象的元素,添加时会命名为userList
- 一个x.y.Foo[]数组,包含了0个或多个x.y.User对象的元素,添加时会命名为fooList
- 一个java.util.HashSet,包含了0个或多个x.y.Foo元素,添加时会命名为fooList
- 一个空的java.util.ArrayList不会添加到其中。(会导致addObject(..)方法无实际操作)