zoukankan      html  css  js  c++  java
  • Spring中Model、ModelMap、ModelAndView理解和具体使用总结

    1.隐含模型

    在了解这三者之前,需要知道一点:SpringMVC在调用方法前会创建一个隐含的数据模型,作为模型数据的存储容器, 成为”隐含模型”。
    也就是说在每一次的前后台请求的时候会随带这一个背包,不管你用没有,这个背包确实是存在的,用来盛放我们请求交互传递的值;关于这一点,spring里面有一个注解:
    @ModelAttribute :被该注解修饰的方法,会在每一次请求时优先执行,用于接收前台jsp页面传入的参数
    例子:

    
    @Controller
    public class User1Controller{
    
    private static final Log logger = LogFactory.getLog(User1Controller.class);
    
    // @ModelAttribute修饰的方法会先于login调用,该方法用于接收前台jsp页面传入的参数
    @ModelAttribute
    public void userModel(String loginname,String password,
             Model model){
        logger.info("userModel");
        // 创建User对象存储jsp页面传入的参数
        User2 user = new User2();
        user.setLoginname(loginname);
        user.setPassword(password);
        // 将User对象添加到Model当中
        model.addAttribute("user", user);
    }
    
    @RequestMapping(value="/login1")
     public String login(Model model){
        logger.info("login");
        // 从Model当中取出之前存入的名为user的对象
        User2 user = (User2) model.asMap().get("user");
        System.out.println(user);
        // 设置user对象的username属性
        user.setUsername("测试");
        return "result1";
    }
    

    2.Mode和ModelMap的区别

    在前端向后台请求时,spring会自动创建Model与ModelMap实例,我们只需拿来使用即可;

    在这里插入图片描述

    无论是Mode还是ModelMap底层都是使用BindingAwareModelMap,所以两者基本没什么区别;
    我们可以简单看一下两者区别:

    ①Model

    Model是一个接口,它的实现类为ExtendedModelMap,继承ModelMap类

    public class ExtendedModelMap extends ModelMap implements Model

    ②ModelMap

    ModelMap继承LinkedHashMap,spring框架自动创建实例并作为controller的入参,用户无需自己创建

    public class ModelMap extends LinkedHashMap

    而是对于ModelAndView顾名思义,ModelAndView指模型和视图的集合,既包含模型 又包含视图;ModelAndView的实例是开发者自己手动创建的,这也是和ModelMap主要不同点之一;ModelAndView其实就是两个作用,一个是指定返回页面,另一个是在返回页面的同时添加属性;

    3.构造方法对应的使用方法

    a 它有很多构造方法,对应会有很多使用方法:
    例子:
    (1)当你只有一个模型属性要返回时,可以在构造器中指定该属性来构造ModelAndView对象:

     public class WelcomeController extends AbstractController{  
        public ModelAndView handleRequestInternal(HttpServletRequest request,  
            HttpServletResponse response)throws Exception{  
            Date today = new Date();  
            return new ModelAndView("welcome","today",today);  
        }  
    } 
    

    (2)如果有不止一个属性要返回,可以先将它们传递到一个Map中再来构造ModelAndView对象

    
    public class ReservationQueryController extends AbstractController{  
        ...  
        public ModelAndView handleRequestInternal(HttpServletRequest request,  
            HttpServletResponse response)throws Exception{  
            ...  
            Map<String,Object> model = new HashMap<String,Object>();  
            if(courtName != null){  
                model.put("courtName",courtName);  
                model.put("reservations",reservationService.query(courtName));  
            }  
            return new ModelAndView("reservationQuery",model);  
        }  
    }  
    

    当然也可以使用spring提供的Model或者ModelMap,这是java.util.Map实现;

    public class ReservationQueryController extends AbstractController{  
        ...  
        public ModelAndView handleRequestInternal(HttpServletRequest request,  
            HttpServletResponse response)throws Exception{  
            ...  
            ModelMap model = new ModelMap();  
            if(courtName != null){  
                model.addAttribute("courtName",courtName);  
                model.addAttribute("reservations",reservationService.query(courtName));  
            }  
            return new ModelAndView("reservationQuery",model);  
        }  
    }  
    

    在页面上可以通过el变量方式${key}或者bboss的一系列数据展示标签获取并展示modelMap中的数据;上面主要讲了ModelAndView的使用,其实Model与ModelMap使用方法都是一致;

    下面我通过一个下例子展示一下:
    在spring项目中,在配置文件中配置好 视图解析器:

    <!-- 视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 前缀 -->
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <!-- 后缀 -->
            <property name="suffix" value=".jsp"/>
        </bean>
    

    在后台写

        @RequestMapping("/test1")
        public ModelAndView test1(ModelMap mm ,HttpServletRequest request){
            ModelAndView mv = new ModelAndView("mytest");
            mv.addObject("key1","123");
            mm.addAttribute("key1","1234");
            return mv;
        }//前端为 123 123
    
        @RequestMapping("/test2")
        public String test2(ModelMap mm ,HttpServletRequest request){
            mm.addAttribute("key1", "1234");
            return "mytest";
        }//前端为 1234 1234 
    
        @RequestMapping("/test3")
        public String test3(Model mm ,HttpServletRequest request){
            mm.addAttribute("key1", "12345");
            return "mytest";
        }
    
        @RequestMapping("/test4")
        public String test4(Model mm ,HttpServletRequest request){
            mm.addAttribute("key1", "12345");
            request.setAttribute("key1", "123456");
            return "mytest";
        }//前端为 12345 12345
    
        @RequestMapping("/test5")
        public String test5(Model mm ,ModelMap mmp,HttpServletRequest request){
            request.setAttribute("key1", "123456");
            mm.addAttribute("key1", "12345");
            mmp.addAttribute("key1", "1234567");
            return "mytest";
        }//前端为 1234567 1234567
    

    从上面测试可以看到Model,ModelMap与ModelAndView的具体使用;同时可以看出Model与ModelMap的值是能够替换的;并且两者赋值后作用比request.setAttribute()要大;这点在使用时需要注意;具体为啥,估计是最终解析时还是放在request上,最终还是替换了;我们知道

    终上所述,我们知道了Model与ModelMap其实都是实现了hashMap,并且用法都是一样的;两者都是spring在请求时自动生成,拿来用便可;ModelAndView就是在两者的基础上可以指定返回页面;
    赋值能力 ModelAndView > Model/ModelMap>request ;

  • 相关阅读:
    报错:无法截断表 '某表',因为该表正由 FOREIGN KEY 约束引用
    如何选择使用结构或类
    C#交换两个变量值的多种写法
    什么是.Net, IL, CLI, BCL, FCL, CTS, CLS, CLR, JIT
    把数据库中有关枚举项值的数字字符串转换成文字字符串
    为参数类型一样返回类型不同的接口写一个泛型方法
    报错:System.NotSupportedException: LINQ to Entities does not recognize the method
    关于泛型类和扩展方法的一点思考
    在ASP.NET MVC下通过短信验证码注册
    ASP.NET MVC下实现前端视图页的Session
  • 原文地址:https://www.cnblogs.com/jia0504/p/14019494.html
Copyright © 2011-2022 走看看