SpringMVC基础-04

数据输出:如何将数据带给页面

  1 package com.atguigu.controller;
  2 
  3 import java.util.Map;
  4 
  5 import org.springframework.stereotype.Controller;
  6 import org.springframework.ui.Model;
  7 import org.springframework.ui.ModelMap;
  8 import org.springframework.web.bind.annotation.RequestMapping;
  9 import org.springframework.web.bind.annotation.SessionAttributes;
 10 import org.springframework.web.servlet.ModelAndView;
 11 
 12 /**
 13  * SpringMVC除过在方法上传入原生的request和session外还能怎么样把数据带给页面
 14  * 
 15  * 1)、可以在方法处传入Map、或者Model或者ModelMap 16  *         给这些参数里面保存的所有数据都会放在请求域中。可以在页面获取
 17  *   关系:
 18  *       Map,Model,ModelMap:最终都是BindingAwareModelMap在工作;
 19  *       相当于给BindingAwareModelMap中保存的东西都会被放在请求域中;
 20  * 
 21  *         Map(interface(jdk))      Model(interface(spring))  
 22  *             ||                            //
 23  *             ||                           //
 24  *             /                          //
 25  *         ModelMap(clas)                 //
 26  *                     \                //
 27  *                      \               //
 28  *                     ExtendedModelMap
 29  *                             ||
 30  *                             /
 31  *                     BindingAwareModelMap
 32  * 
 33  * 2)、方法的返回值可以变为ModelAndView类型;
 34  *             既包含视图信息(页面地址)也包含模型数据(给页面带的数据);
 35  *             而且数据是放在请求域中;
 36  *             request、session、application;
 37  *             
 38  * 3)、SpringMVC提供了一种可以临时给Session域中保存数据的方式;
 39  *     使用一个注解    @SessionAttributes(只能标在类上)
 40  *     @SessionAttributes(value="msg"):
 41  *         给BindingAwareModelMap中保存的数据,或者ModelAndView中的数据,
 42  *         同时给session中放一份;
 43  *         value指定保存数据时要给session中放的数据的key;
 44  * 
 45  *     value={"msg"}:只要保存的是这种key的数据,给Session中放一份
 46  *     types={String.class}:只要保存的是这种类型的数据,给Session中也放一份
 47  * 
 48  *  后来推荐@SessionAttributes就别用了,可能会引发异常;
 49  *             给session中放数据请使用原生API;
 50  *     
 51  * @author lfy
 52  *
 53  */
 54 @SessionAttributes(value={"msg"},types={String.class})
 55 @Controller
 56 public class OutputController {
 57     
 58     //args:如何确定目标方法每一个参数的值;最难?
 59     // method.invoke(this,args)
 60     @RequestMapping("/handle01")
 61     public String handle01(Map<String, Object> map){
 62         map.put("msg", "你好");
 63         map.put("haha", "哈哈哈");
 64         System.out.println("map的类型:"+map.getClass());
 65         return "success";
 66     }
 67     
 68     /**
 69      * Model:一个接口
 70      * @param model
 71      * @return
 72      */
 73     @RequestMapping("/handle02")
 74     public String handle02(Model model){
 75         model.addAttribute("msg", "你好坏!");
 76         model.addAttribute("haha", 18);
 77         System.out.println("model的类型:"+model.getClass());
 78         return "success";
 79     }
 80     
 81     @RequestMapping("/handle03")
 82     public String handle03(ModelMap modelMap){
 83         modelMap.addAttribute("msg", "你好棒!");
 84         System.out.println("modelmap的类型:"+modelMap.getClass());
 85         return "success";
 86     }
 87     
 88     /**
 89      * 返回值是ModelAndView;可以为页面携带数据
 90      * @return
 91      */
 92     @RequestMapping("/handle04")
 93     public ModelAndView handle04(){
 94         //之前的返回值我们就叫视图名;视图名视图解析器是会帮我们最终拼串得到页面的真实地址;
 95         //ModelAndView mv = new ModelAndView("success");
 96         ModelAndView mv = new ModelAndView();
 97         mv.setViewName("success");
 98         mv.addObject("msg", "你好哦!");
 99         return mv;
100     }
101 
102 }

ModelAttribute(由于MyBatis的使用,该注解已经不常用了)

使用场景:
  1)页面:
  1 package com.atguigu.controller;
  2 
  3 import java.util.Map;
  4 
  5 import javax.servlet.http.HttpServletRequest;
  6 
  7 import org.springframework.stereotype.Controller;
  8 import org.springframework.ui.Model;
  9 import org.springframework.web.bind.annotation.ModelAttribute;
 10 import org.springframework.web.bind.annotation.RequestMapping;
 11 import org.springframework.web.bind.annotation.RequestParam;
 12 
 13 import com.atguigu.bean.Book;
 14 
 15 /**
 16  * 测试ModelAttribute注解;
 17  * 使用场景:书城的图书修改为例;
 18  * 1)页面端;
 19  *         显示要修改的图书的信息,图书的所有字段都在
 20  * 2)servlet收到修改请求,调用dao;
 21  *         String sql="update bs_book set title=?,
 22  *                     author=?,price=?,
 23  *                     sales=?,stock=?,img_path=?
 24  *                 where id=?";
 25  * 3)实际场景?
 26  *         并不是全字段修改;只会修改部分字段,以修改用户信息为例;
 27  *         username  password  address;
 28  *         1)、不修改的字段可以在页面进行展示但是不要提供修改输入框;
 29  *         2)、为了简单,Controller直接在参数位置来写Book对象
 30  *         3)、SpringMVC为我们自动封装book;(没有带的值是null)
 31  *         4)、如果接下来调用了一个全字段更新的dao操作;会将其他的字段可能变为null;
 32  *             sql = "update bs_book set"
 33  *             if(book.getBookName()){
 34  *                 sql +="bookName=?,"
 35  *             }
 36  *             if(book.getPrice()){
 37  *                 sql +="price=?"
 38  *             }
 39  *
 40  * 4)、如何能保证全字段更新的时候,只更新了页面携带的数据;
 41  *         1)、修改dao;代价大?
 42  *         2)、Book对象是如何封装的?
 43  *             1)、SpringMVC创建一个book对象,每个属性都有默认值,bookName就是null;
 44  *                 1、让SpringMVC别创建book对象,直接从数据库中先取出一个id=100的book对象的信息
 45  *                 2、Book [id=100, bookName=西游记, author=张三, stock=12, sales=32, price=98.98]
 46  *
 47  *             2)、将请求中所有与book对应的属性一一设置过来;
 48  *                 3、使用刚才从数据库取出的book对象,给它 的里面设置值;(请求参数带了哪些值就覆盖之前的值)
 49  *                 4、带了的字段就改为携带的值,没带的字段就保持之前的值
 50  *             3)、调用全字段更新就有问题;
 51  *                 5、将之前从数据库中查到的对象,并且封装了请求参数的对象。进行保存;
 52  *
 53  */
 54 @Controller
 55 public class ModelAttributeTestController {
 56 
 57     private Object o1;
 58     private Object o2;
 59 
 60     private Object b1;
 61     private Object b2;
 62 
 63     //bookDao.update(book);
 64     //Book [id=100, bookName=null, author=张三, stock=12, sales=32, price=98.98]
 65     /**
 66      *        String sql="update bs_book set bookName=?,
 67      author=?,price=?,
 68      sales=?,stock=?,img_path=?
 69      where id=?";
 70      */
 71     /**
 72      * 可以告诉SpringMVC不要new这个book了我刚才保存了一个book;
 73      * 哪个就是从数据库中查询出来的;用我这个book?
 74      *
 75      *
 76      * 同都是BindingAwareModelMap
 77      * @param book
 78      * @return
 79      */
 80     @RequestMapping("/updateBook")
 81     public String updateBook(@RequestParam(value="author")String author,
 82                              Map<String, Object> model,
 83                              HttpServletRequest request,
 84                              @ModelAttribute("haha")Book book
 85     ){
 86         o2 = model;
 87         b2  = book;
 88         Object haha = model.get("haha");
 89         //System.out.println("传入的model:"+model.getClass());
 90         System.out.println("o1==o2?"+(o1 == o2));
 91         System.out.println("b1==b2?"+(b1 == b2)+"-->"+(b2 == haha));
 92 
 93         System.out.println("页面要提交过来的图书信息:"+book);
 94         return "success";
 95     }
 96 
 97     /**
 98      * 1)、SpringMVC要封装请求参数的Book对象不应该是自己new出来的。
 99      *         而应该是【从数据库中】拿到的准备好的对象
100      * 2)、再来使用这个对象封装请求参数
101      *
102      * @ModelAttribute:
103      *         参数:取出刚才保存的数据
104      *         方法位置:这个方法就会提前于目标方法先运行;
105      *             1)我们可以在这里提前查出数据库中图书的信息
106      *             2)将这个图书信息保存起来(方便下一个方法还能使用)
107      *
108      * 参数的map:BindingAwareModelMap
109      */
110     @ModelAttribute
111     public void hahaMyModelAttribute(Map<String, Object> map){
112 
113         Book book = new Book(100, "西游记", "吴承恩", 98, 10, 98.98);
114         System.out.println("数据库中查到的图书信息是:"+book);
115         map.put("haha", book);
116         b1 = book;
117         o1 = map;
118         System.out.println("modelAttribute方法...查询了图书并给你保存起来了...他用的map的类型:"+map.getClass());
119     }
120 
121 }
原文地址:https://www.cnblogs.com/116970u/p/13161711.html