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 ;

  • 相关阅读:
    zoj 3627#模拟#枚举
    Codeforces 432D Prefixes and Suffixes kmp
    hdu 4778 Gems Fight! 状压dp
    CodeForces 379D 暴力 枚举
    HDU 4022 stl multiset
    手动转一下田神的2048
    【ZOJ】3785 What day is that day? ——KMP 暴力打表找规律
    poj 3254 状压dp
    C++中运算符的优先级
    内存中的数据对齐
  • 原文地址:https://www.cnblogs.com/jia0504/p/14019494.html
Copyright © 2011-2022 走看看