18.13.2Model ModelMap (ModelAndView)
ModelMap类本质上是一个荣耀的Map,它可以使添加的对象在View中(或在其上)显示,并遵循一个通用的命名约定。 考虑下面的控制器实现; 注意到对象被添加到ModelAndView而没有指定任何关联的名字。
public class DisplayShoppingCartController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
        List cartItems = // 获取CartItem对象的列表
        User user = // 让用户进行购物
        ModelAndView mav = new ModelAndView("displayShoppingCart"); <-- 逻辑视图名称
        mav.addObject(cartItems); <-- 看ma,没有名字,只是对象
        mav.addObject(user); <-- and again ma!
        return mav;
    }
}
ModelAndView类使用一个ModelMap类,它是一个自定义的Map实现,当一个对象被添加到它时,该实现自动为一个对象生成一个键。 在像User这样的标量对象的情况下,为添加对象确定名称的策略是使用对象类的简短类名称。 以下示例是为放置在ModelMap实例中的标量对象生成的名称。
x.y.User添加 的实例将生成名称user。x.y.Registration添加 的实例将生成名称registration。x.y.Foo添加 的实例将生成名称foo。java.util.HashMap添加的实例将生成名称hashMap。 你可能想在这种情况下明确名称,因为hashMap不是直观的。添加
null将导致引发IllegalArgumentException。 如果要添加的对象(或多个对象)可能为null,那么您还需要明确名称。
什么,没有自动多元化?
Spring Web MVC的常规配置支持支持不支持自动多元化。 也就是说,不能将一个List的Person对象列表添加到ModelAndView中,并将生成的名称作为people。
这个决定是经过一番辩论后做出来的,最后以“最低惊奇原则”获胜。
添加一个Set或者一个List之后生成一个名字的策略就是查看这个集合,获取这个集合中第一个对象的简短类名,并且在名字后面加上List。 对于数组也是如此,但是对于数组,不需要查看数组的内容。 一些例子会使集合的名字生成的语义更清晰:
添加了零个或多个
x.y.User元素的x.y.User[]数组将生成名称userList。添加了零个或多个
x.y.User元素的x.y.Foo[]数组将会生成名称fooList。添加了一个或多个
x.y.User元素的java.util.ArrayList将生成的名称userList。添加了一个或多个
x.y.Foo元素的java.util.HashSet将具有生成的名称fooList。根本不会添加 一个空
java.util.ArrayList(实际上,addObject(..)调用本质上是无操作的)。