亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

【譯】理解SpringMVCModelAttribute和SessionAttribute

2019-11-14 15:25:07
字體:
來源:轉載
供稿:網友

作為一名 java Web 應用開發者,你已經快速學習了 request(HttpServletRequest)和 session(HttpSession)作用域。在設計和構建 Java Web 應用時,理解這些作用域,如何將數據與對象和這些作用域交互是十分重要的?!驹?StackOverflow 上有一篇文章可以幫助你快速了解 request 和 session 作用域】

SPRING MVC 作用域

當我開始用 Spring MVC 編寫 Web 應用時,我發現 Spring model 和 session attribute 有一點神秘,尤其當它們與我熟知的 HTTP request 和 session 作用域交互時。一個 Spring model 元素可以從我的 session 或者 request 中找到嗎?如果是這樣的話,我該如何控制?在這篇文章中,我希望講解清楚 Spring MVC 的 model 與 session 是如何工作的。

SPRING 的 @MODELATTRIBUTE

有幾種方法將數據或對象添加到 Spring 的 model 中。一般來說,數據或對象是通過 controller 層的一個注解添加進 Spring 的 model 中。在下面的例子中,使用 @ModelAttribute 添加一個名為 MyCommandBean 的實例給 key 值為『myRequestObject』的 model。

 1 public class MyController { 2   3     @ModelAttribute("myRequestObject") 4     public MyCommandBean addStuffToRequestScope() { 5         System.out.println("Inside of addStuffToRequestScope"); 6         MyCommandBean bean = new MyCommandBean("Hello World",42); 7         return bean; 8     } 9  10     @RequestMapping("/dosomething")11     public String requestHandlingMethod(Model model, HttpServletRequest request) {12         System.out.println("Inside of dosomething handler method");13  14         System.out.println("--- Model data ---");15         Map modelMap = model.asMap();16         for (Object modelKey : modelMap.keySet()) {17             Object modelValue = modelMap.get(modelKey);18             System.out.println(modelKey + " -- " + modelValue);19         }20  21         System.out.println("=== Request data ===");22         java.util.Enumeration reqEnum = request.getAttributeNames();23         while (reqEnum.hasMoreElements()) {24             String s = reqEnum.nextElement();25             System.out.println(s);26             System.out.println("==" + request.getAttribute(s));27         }28  29         return "nextpage";30     }31  32          //  ... the rest of the controller33 }

在一個到達的 request 中,任何被 @ModelAttribute 注解的方法都會在 controller handler method 之前調用(就像上面例子中的 requestHandlingMethod 一樣)。這些方法會趕在 handler method 執行之前將數據添加進一個 java.util.Map,然后加入 Spring model 中??梢杂靡粋€示例操作展示出來。我創建了兩個 jsp 頁面:index.jsp 和 nextpage.jsp。index.jsp 上的一個鏈接用于向 MyController 中的 requestHandlingMethod() 應用觸發器發送一個 request。上面的代碼中,requestHandlingMethod() 將『nextpage』作為下個視圖的邏輯名返回,其在這個例子中會處理為 nextpage.jsp。

當這個小小的網址被修改為這種形式后,controller 的 System.out.println 展現了 @ModelAttribute 方法是如何在 handler method 之前執行的。同時也展現了 MyCommandBean 創建和加入 Spring model,并在 handler method 中可用的過程。

 1 Inside of addStuffToRequestScope 2 Inside of dosomething handler method 3 --- Model data --- 4 myRequestObject -- MyCommandBean [someString=Hello World, someNumber=42] 5 === Request data === 6 org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE 7 ==WebapplicationContext for namespace 'dispatcher-servlet': startup date [Sun Oct 13 21:40:56 CDT 2013]; root of context hierarchy 8 org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER 9 ==org.springframework.web.servlet.theme.FixedThemeResolver@204af48c10 org.springframework.web.servlet.DispatcherServlet.CONTEXT11 ==WebApplicationContext for namespace 'dispatcher-servlet': startup date [Sun Oct 13 21:40:56 CDT 2013]; root of context hierarchy12 org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping13 ==dosomething.request14 org.springframework.web.servlet.HandlerMapping.bestMatchingPattern15 ==/dosomething.*16 org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER17 ==org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@18fd23e4

 

現在問題變為了『Spring model 的數據存儲在哪里?』是存儲在標準 Java request 作用域中么?答案是 —— 對的。。。就最終而言的話。就像你從上面的輸出中讀到的,MyCommandBean 在 model 中,但當 handler method 執行時還不在 request 對象中。的確,handler method 執行之后,下個視圖(本例中為 nextpage.jsp)顯示之前為止,Spring 都沒有將 model 數據作為 attribute 加入 request 中。

也可以通過輸出存儲在 index.jsp 與 nextpage.jsp 的 HttpServletRequest 中的 attribute 展現出來。我在兩個頁面中都布置了一個 JSP 代碼塊(如下面所示),用以展現 HttpServletRequest 的 attribute。

 1 <h3>Request Scope (key==values)</h3> 2 <% 3     java.util.Enumeration<String> reqEnum = request.getAttributeNames(); 4     while (reqEnum.hasMoreElements()) { 5         String s = reqEnum.nextElement(); 6         out.print(s); 7         out.println("==" + request.getAttribute(s)); 8 %><br /> 9 <%10     }11 %>

 

當應用啟動,index.jsp 加載完畢,你可以看到在 request 作用域中沒有 attribute。

requestattributesbefore

在本例中,當『do something』被點擊時執行 MyController 的 handler method,然后會跳轉并展示 nextpage.jsp。而 nextpage.jsp 中已經編寫了相同的 JSP 代碼塊,同樣提供了 request 作用域中的 attribute。瞧,當 nextpage.jsp 渲染后,顯示出在 controller 中創建的 MyCommandBean model 被加進 HttpServletRequest 作用域中了!Spring model attribute 的鍵值『myRequestObject』被復制后用作 request attribute 的鍵值。

所以下一個視圖呈現之前,Spring model 數據已經在 handler method 執行之前(或者之間)被拷貝給了 HttpServletRequest。

使用 SPRING MODEL 與 REQUEST 的原因

你或許想知道為什么 Spring 使用 model attribute。為何不直接把數據加到 request 對象里?我在 Rod Johnson 等人的書籍《Professional Java Development with the Spring Framework》中找到了答案。這本書關于 Spring API 的部分有一點過時(基于 Spring 2.0 編寫),但是我發現該書提供了一些對于 Spring 引擎運行的擴展解釋。下面是書中 model 元素部分的引用:

直接將元素加入 HttpServletRequest(像 request attributes 一樣)看起來就像在服務同樣的目標。這樣做的理由是當看到我們為 MVC 框架設置的 requirements 時,能夠更明確。它應盡可能與視圖無關,這意味著我們可以合并視圖技術,并不受 HttpServletRequest 的束縛。

SPRING 的 @SESSIONATTRIBUTES

所以現在你知道了 Spring 如何管理 model 數據,與如何連接標準的 Http request attribute 數據。那么關于 Spring 的 session 數據呢?

Spring 的 @SessionAttribute 在 controller 中用來指定哪一個 model attributes 需要存儲到 session。事實上,Spring 文檔聲明了 @SessionAttributes 注解『列舉需要顯式地存儲 session 或一些交互用的存儲空間內的 model attributes 名稱?!涣硗庹f一下,『一些交互存儲空間』表明了 Spring MVC 試圖保持與技術無關聯的設計思想。

事實上,@SessionAttributes 允許你做的就是告訴 Spring 哪一個 model attributes 將在視圖展現之前一同拷貝給 HttpSession。關于這一點同樣可以用一個簡短的代碼來展示。

在 index.jsp 和 nextpage.jsp 中,我添加了額外的 JSP 代碼塊,使其顯示 HttpSession attributes。

 1 <h3>Session Scope (key==values)</h3> 2 <% 3   java.util.Enumeration<String> sessEnum = request.getSession() 4     .getAttributeNames(); 5   while (sessEnum.hasMoreElements()) { 6     String s = sessEnum.nextElement(); 7     out.print(s); 8     out.println("==" + request.getSession().getAttribute(s)); 9 %><br />10 <%11   }12 %>

 

我使用 @SessionAttributes 注解 MyController,使其將同一個 model attributes(myRequestObject)放入 Spring session 中。

1 @Controller2 @SessionAttributes("myRequestObject")3 public class MyController {4   ...5 }

 

另外在 controller 的 handler method 中添加代碼顯示 HttpSession 中的 attributes(就像顯示 HttpServletRequest 中的 attributes 一樣)。

 1 @SuppressWarnings("rawtypes") 2 @RequestMapping("/dosomething") 3 public String requestHandlingMethod(Model model, HttpServletRequest request, HttpSession session) { 4   System.out.println("Inside of dosomething handler method"); 5   6   System.out.println("--- Model data ---"); 7   Map modelMap = model.asMap(); 8   for (Object modelKey : modelMap.keySet()) { 9     Object modelValue = modelMap.get(modelKey);10     System.out.println(modelKey + " -- " + modelValue);11   }12  13   System.out.println("=== Request data ===");14   java.util.Enumeration<String> reqEnum =         request.getAttributeNames();15   while (reqEnum.hasMoreElements()) {16     String s = reqEnum.nextElement();17     System.out.println(s);18     System.out.println("==" + request.getAttribute(s));19   }20  21   System.out.println("*** Session data ***");22   Enumeration<String> e = session.getAttributeNames();23   while (e.hasMoreElements()){24     String s = e.nextElement();25     System.out.println(s);26     System.out.println("**" + session.getAttribute(s));27   }28  29   return "nextpage";30 }

現在,我們可以看見加上 @SessionAttributes 注解后,Spring MVC 處理一個 HTTP 請求之前、之間和之后的 session 對象情況。下面顯示了結果。首先,當 index.jsp 顯示時(請求被 Spring MVC 發送和處理之前),我們可以看見 HttpServletRequest 和 HttpSession 都沒有 attribute 數據。

before-request-attribute-list

handler method 執行時(requestHandlingMethod),你可以看見 MyCommandBean 被添加進 Spring model attributes,但是還沒有加入 HttpServletRequest 或 HttpSession 作用域。

但是 handler method 執行后和 nextpage.jsp 顯示時,你可以看見 model attribute 數據(MyCommandBean)已經作為一個 attribute 被復制給了 HttpServletRequest 和 HttpSession(擁有相同的 attribute key)。

控制 SESSION ATTRIBUTES

現在你已經理解了 Spring model 和 session attribute 數據如何添加進 HttpServletRequest 與 HttpSession?;蛟S又開始關心怎么管理 Spring session 中的數據。Spring 提供了一個方法移除 Spring session attributes,同時也會從 HttpSession 中移除(不需要刪除整個 HttpSession)。簡單地將一個 Spring SessionStatus 對象作為參數加入一個 controller handler method 中。在此方法中,使用 SessionStatus 對象結束這個 Spring session。

1 @RequestMapping("/endsession")2 public String nextHandlingMethod2(SessionStatus status){3   status.setComplete();4   return "lastpage";5 }

 

總結

希望這篇文章能夠幫助你理解 Spring model 和 session attributes。這并不神奇,僅僅是一個理解 HttpSession 和 HttpServletRequest 如何存儲 Spring model 和 session attributes 的問題。我已經將展示用的代碼放在了 Intertech Web site 上。如果你對繼續探索與理解 Spring model 和 session 感興趣,盡管從這里下載吧。

如果你對深入學習 Spring(或任何一種 Java 技術)感興趣,可以考慮馬上注冊,成為 Intertech 的一員。在這里學到更多與注冊。


原文鏈接: Intertech
首發于 importnew,譯文鏈接: http://www.importnew.com/16782.html

已同步至 Github,歡迎 Star 關注更新。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情视频在线免费观看 欧美视频免费一| www.日本久久久久com.| 欧美丝袜一区二区| 91香蕉国产在线观看| 成人美女免费网站视频| 欧美裸体xxxx极品少妇软件| 97免费在线视频| 欧美在线www| 中文字幕欧美亚洲| www.亚洲一区| 亚洲网站在线观看| 亚洲男人的天堂在线| 欧美精品中文字幕一区| 国产精品人成电影在线观看| 黑人巨大精品欧美一区二区三区| 久久久国产精品视频| 久久久成人精品视频| 国产视频自拍一区| 欧美成人精品一区二区| 色偷偷偷综合中文字幕;dd| 国产精品扒开腿做爽爽爽男男| 亚洲一区二区中文字幕| 在线观看视频99| 国产91在线播放| 亚洲欧美日韩在线高清直播| 久久精品视频中文字幕| 美女撒尿一区二区三区| 亚洲欧洲在线免费| 亲子乱一区二区三区电影| 亚洲天堂男人天堂| www.亚洲男人天堂| 国产精品偷伦视频免费观看国产| 亚洲天天在线日亚洲洲精| 久久精品国产久精国产思思| 亚洲全黄一级网站| 这里只有精品在线播放| 97在线看免费观看视频在线观看| 亚洲欧美中文日韩在线| 国产精品一区二区三区免费视频| 欧美日韩一区二区三区在线免费观看| 国产欧美日韩中文| 日韩av一区在线观看| 欧美最猛性xxxx| 国产91色在线免费| 欧美一级bbbbb性bbbb喷潮片| 北条麻妃一区二区三区中文字幕| 国语自产精品视频在线看| 亚洲国产欧美自拍| 在线午夜精品自拍| 欧美极品少妇xxxxⅹ喷水| 欧美日韩精品中文字幕| 国产精品女视频| 国产一区二区在线免费| 国产一区av在线| 亚洲国语精品自产拍在线观看| 久久久久久久久久久久久久久久久久av| 久久九九全国免费精品观看| 亚洲人成欧美中文字幕| 欧美多人爱爱视频网站| 欧美电影在线免费观看网站| 亚洲人成网在线播放| 亚洲欧美在线免费| 国产精品吊钟奶在线| 高跟丝袜一区二区三区| 国产精品美女免费| 国产精品久久91| 国产91精品网站| 97成人在线视频| 性亚洲最疯狂xxxx高清| 日韩美女写真福利在线观看| 国产精品久久久久久久久借妻| 精品无人区太爽高潮在线播放| 亚洲欧美自拍一区| 日韩一区在线视频| 日韩欧美在线视频| 中文字幕亚洲无线码在线一区| 日韩最新av在线| 国产精品亚洲自拍| 久久久久久久久中文字幕| 欧美亚洲第一区| 丰满岳妇乱一区二区三区| 国产日韩av在线播放| 日本精品久久久| 国产精品女主播视频| 亚洲丝袜一区在线| 欧美激情精品久久久久久大尺度| 亚洲欧美在线一区| 欧美午夜精品久久久久久人妖| 456国产精品| 狠狠做深爱婷婷久久综合一区| 久久久久久国产免费| 91免费国产网站| 国产91在线视频| 91精品国产综合久久香蕉的用户体验| 欧美成人一二三| 91精品国产高清久久久久久| 国产伊人精品在线| 国产亚洲a∨片在线观看| 日韩中文字幕不卡视频| 欧美激情欧美激情| 欧美一级成年大片在线观看| 中国china体内裑精亚洲片| 色爱精品视频一区| xxav国产精品美女主播| 亚洲综合大片69999| 午夜精品久久久久久久久久久久| 亚洲欧美一区二区三区情侣bbw| 日韩av免费看网站| 久久久久久12| 国产精品露脸自拍| 亚洲黄色www| 亚洲高清一二三区| 91精品久久久久久久久久久久久| 成人黄色午夜影院| 日韩精品在线观看网站| 久久国产精品首页| 91视频国产高清| 成人美女av在线直播| 国产精品亚洲精品| 亚洲国产精品视频在线观看| 97精品伊人久久久大香线蕉| 成人免费观看网址| 亚洲欧洲一区二区三区在线观看| 国内精品久久久久久久| 亚洲精品aⅴ中文字幕乱码| 日韩av不卡电影| 久久免费视频观看| 亚洲色图欧美制服丝袜另类第一页| 亚洲成人激情小说| 亚洲成人xxx| 欧美一区视频在线| 国产成人av网址| 欧美乱大交做爰xxxⅹ性3| 日韩av在线看| 国产日韩综合一区二区性色av| 久久久亚洲网站| 日韩成人在线视频观看| 国产午夜精品免费一区二区三区| 伊人av综合网| 国产精品偷伦一区二区| 亚洲第一精品久久忘忧草社区| 大伊人狠狠躁夜夜躁av一区| 欧美日韩一区免费| 欧美中文在线免费| 欧美日韩视频免费播放| 国产福利视频一区二区| 国产精品一区二区久久久| 日韩精品免费电影| 国产精品日韩电影| 日韩亚洲综合在线| 97精品一区二区视频在线观看| 69**夜色精品国产69乱| 美日韩精品免费视频| 国内揄拍国内精品| 欧美中文在线视频| 久久久久久成人| 伊是香蕉大人久久| 中文字幕精品—区二区| 亚洲第一页在线| 国产成人精彩在线视频九色| 日韩欧美在线视频| 成人在线国产精品| 这里只有精品视频在线| 伊人久久精品视频|