1. 程式人生 > >spring mvc(4)處理模型資料

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", "[email protected]");
           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 protected]
      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="[email protected]">
      <br>
      <input type="submit" value="submit">
   </form>

  

//標記的方法會在每個目標方法執行之前被呼叫


    //1.由@ModelAttribute標記的方法,會把每個目標之前被springmvc呼叫
    //[email protected]註解也可以來修飾目標方法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", "[email protected]");
                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引發的異常