zoukankan      html  css  js  c++  java
  • spring mvc(4)处理模型数据

    处理模型数据

    Spring MVC 提供了以下几种途径输出模型数据:
    – ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加
      模型数据
    – Map 及 Model: 入参为org.springframework.ui.Model、org.springframework.ui.
      ModelMap 或 java.uti.Map 时,处理方法返回时,Map
      中的数据会自动添加到模型中。
    – @SessionAttributes: 将模型中的某个属性暂存到
      HttpSession 中,以便多个请求之间可以共享这个属性
    – @ModelAttribute: 方法入参标注该注解后, 入参的对象就会放到数据模型中

     注:下面的代码均来自上一篇的注解代码之后的测试代码!!

     ModelAndView

    控制器处理方法的返回值如果为 ModelAndView, 则其既
    包含视图信息,也包含模型数据信息。
     
     添加模型数据:
    – MoelAndView addObject(String attributeName, Object
    attributeValue)
    – ModelAndView addAllObject(Map<String, ?> modelMap)
     
    设置视图:
    – void setView(View view)
    – void setViewName(String viewName)

    TestRequestMapping.java

       @RequestMapping("/testModelAndView")
         public ModelAndView testModelAndView(){
               
               String viewName="success";
               ModelAndView andView = new ModelAndView(viewName);
               andView.addObject("time", new Date());
               return andView;
         }
    

    index.jsp

    <a href="springmvc/testModelAndView">testModelAndView</a>
    

    success.jsp;

         time:${requestScope.time}

    总结:SpringMVC会把ModelAndView的model中数据放入到request域对象中

     Map 及 Model

     Spring MVC 在内部使用了一个org.springframework.ui.Model 接口存储模型数据

    具体步骤
    – Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
     
    – 如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传
      递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数
      据,也可以向模型中添加新的属性数据

    目标方法可以添加Map类型(实际上是Model或者ModelMap类型)的参数

    TestRequestMapping.java

    @RequestMapping("/testMap")
         public String testMap(Map<String, Object> map){
               map.put("name", "MrChengs");
               
               return "success";
         }

    indexjsp

    <a href="springmvc/testMap">testMap</a>

    success.jsp

    name:${requestScope.name}
    

      

    @SessionAttributes

     只能放在类的上面

    若希望在多个请求之间共用某个模型属性数据,则可以在
    控制器类上标注一个 @SessionAttributes, Spring MVC
    将在模型中对应的属性暂存到 HttpSession 中。
    @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(value)
    还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(type)
     – @SessionAttributes(types=User.class) 会将隐含模型中所有类型
                为 User.class 的属性添加到会话中。
        – @SessionAttributes(value={“user1”, “user2”})
        – @SessionAttributes(types={User.class, Dept.class})
        – @SessionAttributes(value={“user1”, “user2”},
                types={Dept.class})

    TestRequestMapping.java

    @SessionAttributes(value="user")
    @Controller
    @RequestMapping("/springmvc")
    public class TestRequestMapping {
         @RequestMapping("/testSessionAttributes")
         public String  testSessionAttributes(Map<String,Object> map){
               User user = new User("MrChangs", "1234", "1287@qq.com");
               map.put("user", user);
               
               return "success";
         }
    }

    index.jsp

     <a href="springmvc/testSessionAttributes">testSessionAttributes</a>

    success.jsp

               user requestScope:${requestScope.user}
               <br>
               <br>
               user sessionScope:${sessionScope.user}
    

      

    @ModelAttribute

    模拟修改数据路中的数据,有些不能修改。
    index.jsp
     <!--
          模拟修改操作
          1.原始数据:id=1,name=MrChengs,pw=1234,email=MrChengs@qq.com
          2.密码不能修改
          3.表单回显,模拟操作直接在表单填写对应的额属性值
       -->
       <form action="springmvc/ModelAttribute" method="post">
          <input type="hidden" name="id" value="1">
          <br>
          name:<input type="text" name="username" value="MrChengs">
          <br>
          email:<input type="text" name="email" value="MrChengs@qq.com">
          <br>
          <input type="submit" value="submit">
       </form>
    

      

    //标记的方法会在每个目标方法执行之前被调用
    
    
        //1.由@ModelAttribute标记的方法,会把每个目标之前被springmvc调用
        //2.@MOdelAttribute注解也可以来修饰目标方法pojo类型的入参,其value属性值如下作用
        //2.1)springmvc会使用value属性值在implicitModel中查找对应的对象,若存在直接传入到目标方法的入参中
        //2.2)springmvc会把value为key,pojo类型对象为value,存到request中
       
          @ModelAttribute
         public void getUser(@RequestParam(value="id",required=false) Integer id,
                    Map<String,Object> map){             
               if(id != null){
                    User user = new User(1, "MrChengs", "1234", "MrChengs@qq.com");
                    System.out.println("得到一个参数");
    
    
                    //注意:这里的key为users,如果改为users等其他字符,等不到结果,程序可以正常的执行
                //解决方法在下面的代码中
                    map.put("users", user);
               }
         }
         
         @RequestMapping("/ModelAttribute")
         public String testModelAttribute(@ModelAttribute("users")User user){
               System.out.println("update:" + user);
               return "success";
         }
    在success页面:
    可以使用如下的方法获得打印值
    user:${requestScope.users}

    如果不添加@ModelAttribut,在测试中代码的值为null

    运行过程:
    1.执行@ModelAttribute注解修饰的方法,把数据取出防砸map中,map的key为user
    2.SpringMVC从Map中取出User对象,并把表单请求参数放到赋给给该user对象多的对应属性
    3.SpringMVC把上述对象传入目标方法的参数
     
    注意:在MOdelAttribute修饰的方法中,放入map的键需要和入参第一个字母小写的字符串一致

     

    SpringMVC确定目标方法POJO类型入参的过程:
    1.确定一个key
    2.在implicitModel中查找对应的key对象,若存在,则作为入参传入
    3.在implicitModel中不存在key对象,则查找当前的Handler,是都使用了@SessionAttribute对应的                value值若存在则直接传入到方法的入参中,不存在抛异常
    4.若Handler没由标识的@SessionAttribute注解或者@Session Attribute的value值不包含key,则会通过        反射来创建pojo类型的参数,作为目标方法的参数
    5.SpringMVC会把key和value保存到impliciModel中,进而会保存早request中
    关于@SessionAttribute的异常
     
    java类:
    注意这里@SessionAttribute(user)和方法中的user同名
    @SessionAttributes(value="user")
    @Controller
    @RequestMapping("/springmvc")
    public class TestRequestMapping {  
     @RequestMapping("/ModelAttribute")
         public String testModelAttribute(User user){
               System.out.println("update:" + user);
               return "success";
         }
    }
    在ModelAttribute方法的user
    没找到就去@SeeionAttribute中找
    所以此时会报错----抛异常
    解决方案:
    1.写ModelAttribute注解下的方法
    2.表明一个modelAttribute,在第一次查找中赋值,不在第二次找SeesionAttribute
     public String testModelAttribute(@ModelAttribute("acbc")User user){
    十月 16, 2018 4:38:06 下午 org.apache.catalina.core.StandardWrapperValve invoke
    严重: Servlet.service() for servlet [springDispatcherServlet] in context with path [/Spring_MVC_01] threw exception [Session attribute 'user' required - not found in session] with root cause
    org.springframework.web.HttpSessionRequiredException: Session attribute 'user' required - not found in session
         at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.raiseSessionRequiredException(AnnotationMethodHandlerAdapter.java:791)
    

      

     @ModelAttribute

    在方法定义上使用 @ModelAttribute 注解:Spring MVC
    在调用目标处理方法前,会先逐个调用在方法级上标注了
    @ModelAttribute 的方法。
     
    在方法的入参前使用 @ModelAttribute 注解:
    – 可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数定到对象中,再传入入参
     – 将方法入参对象添加到模型中

     由@SessionAttributes引发的异常

    org.springframework.web.HttpSessionRequiredExcept:
    Session attribute 'user' required - not found in session
    如果在处理类定义处标注了@SessionAttributes(“xxx”),则尝试从会话中获取该属性,并将其赋给该入参,然后再用
    请求消息填充该入参对象。如果在会话中找不到对应的属性,则抛出 HttpSessionRequiredException 异常

     

     如何避免@SessionAttributes引发的异常

     

  • 相关阅读:
    【SQL Server数据迁移】32位的机器:SQL Server中查询ORACLE的数据
    ORACLE存储过程,循环语法和游标
    Oracle变量的定义、赋值及使用
    Oracle数据库常用语法
    Windows下将JAVA jar注册成windows服务
    Java压缩图片
    如何去除图片背景?这款一键抠图软件帮你
    远程办公,这 13 个工具比微信、QQ更好用
    java程序在windows后台执行的办法
    Usage of API documented as @since 1.6+……的解决办法
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/9940917.html
Copyright © 2011-2022 走看看