zoukankan      html  css  js  c++  java
  • 0058 Spring MVC如何向视图传值--Model--ModelMap--ModelAndView--@ModelAttribute

    MVC,模型、视图、控制器,请求来了,控制器负责找到Controller进行一通计算,计算的结果放到模型里,再找视图把结果呈现出来。

    请求里一般都包含了一些参数,前面说了,Spring MVC有很多种方式可以拿到这些参数,一通计算之后把结果存到了模型里,但是这模型有哪些,怎样顺顺利利的交给视图呢?

    HttpServletRequest

    这个类简直神通广大,接受参数靠它,传递结果还靠他。当然了,估计后面的Model、ModelAndView都是把它封装在其中的

    ModelAndView

    一接触Spring MVC,肯定先接触的是这个类。该类将视图和模型放在一起,视图名称解析器和视图解析器就到这个类的对象里拿数据,一开始就用它,不说了。

    Model与ModelMap、Map

    还是用前面的上传书籍信息的例子,

    index.html

    <!DOCTYPE html>
    <html>
    <head>
        <title>Spring MVC如何接受浏览器传递来的参数</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
        <form action="addbook" method="POST">
            <fieldset>
                <legend>要上传的参数</legend>
                 书名:<input name="bookname" /><br>
                作者:<input name="author" /><br>
                出版社:<input name="press" /><br>
                ISBN:<input name="isbn" /><br>
                豆瓣评分:<input name="douban" /><br>
            <input type="submit" value="提交" />
            </fieldset>
            
        </form>
    </body>
    </html>
    

    result.jsp

    <%@page pageEncoding="utf-8" 
            contentType="text/html;charset=utf-8" %>
    <html>
        <head>
            <title>返回结果</title>
        </head>
        <body style="color:blue;font-size:18px">
            您输入的书籍信息为:<br>
            书籍的名称:${book.bookname }<br><br>
            书籍的作者:${book.author }<br><br>
            书籍的出版社:${book.press }<br><br>
            书籍的ISBN:${book.isbn }<br><br>
            书籍的豆瓣评分:${book.douban }<br><br>
        </body>
    </html> 
    

    实体类Book省略

    写Controller

    package net.sonng.mvcdemo.controller;
    
    import net.sonng.mvcdemo.entity.Book;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelDemoController {
        @RequestMapping("/addbook")
        public String modelTest(Book book,Model model){  //将Model放在形参当中
            model.addAttribute("book", book);
            return "result";
        }
    }
    

    浏览器访问index.html,输入信息后,来到result.jsp页面,正常输出
    看起来modelTest()方法中压根就没有model的对象,下面调用addAttribute()方法,岂不是要抛NullPointerException异常了。其实Spring MVC在调用这个处理方法之前就已经创建了一个隐含的模型对象,如果处理方法的参数有Model或者ModelMap,那就将这个隐含对象直接传递过去,当然就想咋用就咋用了。

    说了Model,还有ModelMap、Map呢,将上面处理方法的Model换成ModelMap或者Map,其余代码不变。

    上面把Model或者ModelMap放在形参里面是可以的,那放在局部变量里呢?
    Model:这是个接口,找到一个实现类ExtendedModelMap,也是可以的
    ModelMap:也可以
    Map:也是个接口,用HashMap也是可以的。
    所以:这个隐含对象到底是哪个类的对象?

    @ModelAttribute注解----用@ModelAttribute(value="")注释返回值为对象的方法

    这个注解用法有点多,很灵活,从获取请求参数到处理这些数据再到向视图传递数据,一条线从头到尾。
    特别注意:被@ModelAttribute修饰的方法会在该控制器里的其他方法执行前执行,并且每个处理方法执行时都会执行一次
    还是以传递书籍信息作例子

    package net.sonng.mvcdemo.controller;
    
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    import net.sonng.mvcdemo.entity.Book;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelAttributeDemoController {
        
        //加在方法上,该方法返回值是一个对象,相当于以“book”为key,以方法的返回值为value,添加到了model中
        //如果没有指定key,那么默认的key是返回值类型的首字母小写
        @ModelAttribute("book")  
        public Book getBookInfo(Book book){  //注意这里的参数封装,跟处理方法的参数一样:形参同名;实体类;@RequestParam
            System.out.println("getBookInfo方法执行。。。。。");  //该方法会在调用addbook()方法前先调用
            return book;
        }
        
        @RequestMapping("/addbook")
        public String addbook(){
            System.out.println("addbook方法开始执行。。。。。");
            return "result";
        }
    }
    
    

    视图result.jsp如下:

    <%@page pageEncoding="utf-8" 
            contentType="text/html;charset=utf-8" %>
    <html>
        <head>
            <title>返回结果</title>
        </head>
        <body style="color:blue;font-size:18px">
            您输入的书籍信息为:<br>
            书籍的名称:${book.bookname }<br><br>  <!-- @ModelAttribute可以将一个对象传递过来 -->
            书籍的作者:${book.author }<br><br>
            书籍的出版社:${book.press }<br><br>
            书籍的ISBN:${book.isbn }<br><br>
            书籍的豆瓣评分:${book.douban }<br><br>
        </body>
    </html> 
    

    @ModelAttribute注解----用@ModelAttribute(value="")注释处理方法的形参--在处理方法中获取到绑定的对象

    看代码:

    package net.sonng.mvcdemo.controller;
    
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    import net.sonng.mvcdemo.entity.Book;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelAttributeDemoController {
        
        @ModelAttribute("book")
        public Book getBookInfo(Book book){
            System.out.println("getBookInfo方法执行。。。。。");
            return book;
        }
        
        @RequestMapping("/addbook")
        public String addbook(@ModelAttribute("book") Book b){  //该注解注释形参,将getBookInfo绑定的对象赋值给形参b
            b.setBookname("书的名字被改了"); //获取到绑定的对象后,就可以做些修改,然后传递给视图
            System.out.println("addbook方法开始执行。。。。。");
            return "result";
        }
    }
    

    上面的处理方法换成这样,也是可以获得绑定对象的的:

        @RequestMapping("/addbook")
        public String addbook(Model model){
            Book b=(Book)model.asMap().get("book");
            b.setBookname("书的名字被改了");
            System.out.println("addbook方法开始执行。。。。。");
            return "result";
        }
    

    @ModelAttribute注解----用@ModelAttribute注释返回值为void的方法

    看controller代码:

    package net.sonng.mvcdemo.controller;
    
    import net.sonng.mvcdemo.entity.Book;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelAttributeDemoController {
        
        @ModelAttribute  //修饰返回值为void的方法,因为没有返回值,因而不能绑定返回值。在形参中加上Model,在视图中就可以拿到绑定的数据
        public void getBookInfo(Book book,Model model){
            System.out.println("getBookInfo方法执行。。。。。");
            model.addAttribute("book", book);
        }
        
        @RequestMapping("/addbook")
        public String addbook(Model model){
            Book b=(Book)model.asMap().get("book");
            b.setBookname("书的名字被改了");
            System.out.println("addbook方法开始执行。。。。。");
            return "result";
        }
    }
    

    @ModelAttribute和@RequestMapping一起修饰处理方法

    这种情况下,看起来有点奇怪
    Controller代码:

    package net.sonng.mvcdemo.controller;
    
    import net.sonng.mvcdemo.entity.Book;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelAttributeDemoController {
        
        @ModelAttribute("info")
        @RequestMapping("/addbook")
        public String addbook(Book book){
            book.setBookname("书的名字被改了改了");
            return "result";  //这里的result不再是视图名,而是作为字符串返回值成为key为info的对应的value的值,视图名是请求名,也就是addbook
        }
    }
    

    把result.jsp改名为:addbook.jsp,并加一行代码:

    <%@page pageEncoding="utf-8" 
            contentType="text/html;charset=utf-8" %>
    <html>
        <head>
            <title>返回结果</title>
        </head>
        <body style="color:blue;font-size:18px">
            您输入的书籍信息为:<br>
            书籍的名称:${book.bookname }<br><br>
            书籍的作者:${book.author }<br><br>
            书籍的出版社:${book.press }<br><br>
            书籍的ISBN:${book.isbn }<br><br>
            书籍的豆瓣评分:${book.douban }<br><br>
       @ModelAttribute绑定的数据是:${info }           <!-- 加了一行代码 -->
        </body>
    </html> 
    

    访问index.jsp,输入数据提交后,返回如下页面:

    您输入的书籍信息为:
    书籍的名称:书的名字被改了改了   //book的信息还是被传递到了视图中,并且跟@ModelAttribute("info")注解无关
    
    书籍的作者:Craig Walls 沃尔斯
    
    书籍的出版社:人民邮电出版社
    
    书籍的ISBN:9787115417305
    
    书籍的豆瓣评分:8.4
    
    @ModelAttribute绑定的数据是:result   //result成为了绑定值,传递到视图,而不是视图名
    

    总的来说,@ModelAttribute更像是为了将请求参数的封装跟处理方法分离,单独用一个方法负责参数的获取封装

    Spring MVC的请求参数的获取、传递,模型传递,都十分灵活。

  • 相关阅读:
    poj 3068 Bridge Across Islands
    XidianOJ 1086 Flappy v8
    XidianOJ 1036 分配宝藏
    XidianOJ 1090 爬树的V8
    XidianOJ 1088 AK后的V8
    XidianOJ 1062 Black King Bar
    XidianOJ 1091 看Dota视频的V8
    XidianOJ 1098 突击数论前的xry111
    XidianOJ 1019 自然数的秘密
    XidianOJ 1109 Too Naive
  • 原文地址:https://www.cnblogs.com/sonng/p/6648917.html
Copyright © 2011-2022 走看看