• 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的请求参数的获取、传递,模型传递,都十分灵活。

  • 相关阅读:
    【MySQL案件】mysql登录-S失败
    python3使用smtplib发电子邮件
    oracle创建user具体指示
    设计模式的饕餮盛宴
    iOS使用UIScrollView实现左右滑动UITableView和UICollectionView
    MIFARE系列6《射频卡与读写器的通信》
    hdu1286 寻找新朋友 (欧拉功能)
    Python开发环境的搭建(win7)
    2014年度辛星完全解读html部分
    S2SH新手框架建立具体过程
  • 原文地址:https://www.cnblogs.com/sonng/p/6648917.html
Copyright © 2020-2023  润新知