- <? xml ? version = "1.0" ? encoding = "UTF-8" ?> ??
- < web-app ? xmlns = "http://java.sun.com/xml/ns/j2ee" ??
- ???? xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" ? version = "2.4" ??
- ???? xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee???http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" > ??
- ???? <!--?spring??有三種啟用模式?1ContextLoaderServlet?2.ContextLoaderListener?3.ContextLoaderPlugIn--> ??
- ???? < context-param > ??
- ???????? < param-name > contextConfigLocation </ param-name > ??
- ???????? < param-value > /WEB-INF/applicationContext*.xml </ param-value > ??
- ???? </ context-param > ??
- ???? < servlet > ??
- ???????? < servlet-name > action </ servlet-name > ??
- ???????? < servlet-class > ??
- ????????????org.apache.struts.action.ActionServlet??
- ???????? </ servlet-class > ??
- ???????? < init-param > ??
- ???????????? < param-name > config </ param-name > ??
- ???????????? < param-value > ??
- ????????????????/WEB-INF/struts-config.xml,/WEB-INF/struts-config-framework.xml??
- ???????????? </ param-value > ??
- ???????? </ init-param > ??
- ???????? < init-param > ??
- ???????????? < param-name > debug </ param-name > ??
- ???????????? < param-value > 3 </ param-value > ??
- ???????? </ init-param > ??
- ???????? < init-param > ??
- ???????????? < param-name > detail </ param-name > ??
- ???????????? < param-value > 3 </ param-value > ??
- ???????? </ init-param > ??
- ???????? < load-on-startup > 0 </ load-on-startup > ??
- ???? </ servlet > ??
- ???? <!--?Action?--> ??
- ???? < servlet-mapping > ??
- ???????? < servlet-name > action </ servlet-name > ??
- ???????? < url-pattern > *.do </ url-pattern > ??
- ???? </ servlet-mapping > ??
- ???? <!--?歡迎界面?--> ??
- ???? < welcome-file-list > ??
- ???????? < welcome-file > index.html </ welcome-file > ??
- ???? </ welcome-file-list > ??
- ???? <!--?Spring過濾中文字符集?--> ??
- ???? < filter > ??
- ???????? < filter-name > SetCharacterEncoding </ filter-name > ??
- ???????? < filter-class > ??
- ????????????org.springframework.web.filter.CharacterEncodingFilter??
- ???????? </ filter-class > ??
- ???????? < init-param > ??
- ???????????? < param-name > encoding </ param-name > ??
- ???????????? < param-value > UTF-8 </ param-value > ??
- ???????? </ init-param > ??
- ???? </ filter > ??
- ???? <!--?要過濾得類型?--> ??
- ???? < filter-mapping > ??
- ???????? < filter-name > SetCharacterEncoding </ filter-name > ??
- ???????? < url-pattern > *.jsp </ url-pattern > ??
- ???? </ filter-mapping > ??
- ???? < filter-mapping > ??
- ???????? < filter-name > SetCharacterEncoding </ filter-name > ??
- ???????? < url-pattern > *.do </ url-pattern > ??
- ???? </ filter-mapping > ??
- ???? <!--?注冊Spring的request作用域?--> ??
- ???? < listener > ??
- ???????? < listener-class > ??
- ????????????org.springframework.web.context.request.RequestContextListener??
- ???????? </ listener-class > ??
- ???? </ listener > ??
- ????<!--??
- ????????request??
- ????????request表示該針對每一次HTTP請求都會產生一個新的bean,同時該bean僅在當前HTTP?request內有效,配置實例:??
- ????????request、session、global?session使用的時候首先要在初始化web的web.xml中做如下配置:??
- ????????如果你使用的是Servlet?2.4及以上的web容器,那么你僅需要在web應用的XML聲明文件web.xml中增加下述ContextListener即可:??
- ???????? < web-app > ??
- ????????org.springframework.web.context.request.RequestContextListener??
- ????????...??
- ???????? < listener > ??
- ???????? < listener-class > org.springframework.web.context.request.RequestContextListener </ listener-class > ??
- ???????? </ listener > ??
- ????????...??
- ???????? </ web-app > ??
- ??????????
- ????-- > ??
- ???? <!--?OpenSessionInView?--> ??
- ???? < filter > ??
- ???????? < filter-name > OpenSessionInViewFilter </ filter-name > ??
- ???????? < filter-class > ??
- ????????????org.springframework.orm.hibernate3.support.OpenSessionInViewFilter??
- ???????? </ filter-class > ??
- ???????? < init-param > ??
- ???????????? < param-name > singleSession </ param-name > ??
- ???????????? < param-value > true </ param-value > ??
- ???????? </ init-param > ??
- ???? </ filter > ??
- ????<!--??
- ????????org.springframework.orm.hibernate3.support.OpenSessionInViewFilter??
- ????????延遲加載的實現的原理是cglib動態字節碼??
- ????????Hibernate對延遲加載的實現原理是CGLIB動態字節碼生成技術,即返回的實體并非真正的實體對象,而是經過CGLIB處理后的代理實體,當調用某一未經加載的屬性時,代理實體就可以截獲這一調用,然后由Hibernate實現動態加載。??
- ??????????
- ????????如果要使用Hibernate的延遲加載特性,則渲染視圖階段不能關閉事務,因此,事務的范圍變為整個HTTP請求的周期。??
- ??????????
- ????????采用OpenSessionInView模式可以將事務范圍界定在請求開始和渲染視圖結束后,使得Hibernate的Session在視圖渲染時仍有效。有兩種方式實現OpenSessionInView模式,一種是使用Spring提供的OpenSessionInViewInterceptor,如果采用Spring?MVC框架,可以將這個Interceptor加入到Controller的攔截器鏈中,事務在Controller處理前開始,在視圖渲染后結束,如圖11-17所示。??
- ??????????
- ??????????
- ??????????
- ????????如果Web層沒有采用Spring的MVC框架,而是使用Struts等其他MVC框架,甚至沒有使用MVC框架,此時,就無法定義Interceptor,只能采用Filter來實現OpenSessionInView模式。??
- ??????????
- ????????OpenSessionInViewFilter是Spring提供的一個Filter。在OpenSessionInViewFilter模式下,所有的HTTP請求都將被OpenSessionInViewFilter截獲,事務在請求處理前開始,在請求處理完畢后結束,而不管采用何種MVC框架,甚至直接使用JSP,如圖11-18所示。??
- ??????????
- ????????org.springframework.orm.hibernate3.support.OpenSessionInViewFilter(延遲加載,)??
- ??????????
- ????????圖11-18??
- ??????????
- ????????兩種方式各有優劣。OpenSessionInViewInterceptor只能用于Spring?MVC,但是配置簡單,無須過濾URL;OpenSessionInViewFilter適用范圍更廣,但是必須手動配置web.xml文件,并且必須正確過濾URL。??
- ??????????
- ????????無論如何,采用以上兩種方式的目的都是為了使用Hibernate的延遲加載特性。由于事務也是一種數據庫資源,事務持續的時間越久,數據庫資源被鎖定也越久,應用程序的吞吐量就會降低。因此,要盡量將事務限定在最小的范圍內??
- ??????????
- ????-- > ??
- ???? <!--?session的過濾控制用戶在登錄時的權限限制--> ??
- ???? < filter > ??
- ???????? < filter-name > authorizen </ filter-name > ??
- ???????? < filter-class > ??
- ????????????org.springframework.web.filter.DelegatingFilterProxy??
- ???????? </ filter-class > ??
- ???????? < init-param > ??
- ???????????? < param-name > targetFilterLifecycle </ param-name > ??
- ???????????? < param-value > true </ param-value > ??
- ???????? </ init-param > ??
- ???? </ filter > ??
- ????<!--?以前學習框架經常做登錄頁面的demo,輸入正確的id+pwd就返回成功了。。可是這種模式無法阻止通過URL直接訪問其他的頁面,在一個非玩具系統中,控制未登錄用戶的頁面訪問權限是一個基本功能。??
- ??????????
- ????????從實現思路講,驗證一個用戶的有效登錄,大多采用的是登入時候向Session寫一個User認證信息,然后在訪問每個頁面前來判斷Session中是否有認證信息。??
- ??????????
- ????????if(session.get("User")==null)??
- ????????另外有很多網站提供記住登陸信息xx天,這種是結合了Cookie的認證信息存儲。談到這里,也可以仔細想想Cookie和Session的作用。比如卓越的購物車就是Cookie做的(因為關閉IE后再訪問購物車還記得你的物品),而大多數群集Web服務器的信息也是采用Cookie(因為群集的Session同步開銷很大),掌握了Cookie和Session的基本特性,這些都是理所當然的做法了。??
- ??????????
- ????????一。下面說第一種攔截實現:基于javax.servlet.Filter??
- ??????????
- ????????1.首先需要到web.xml注冊一個filter??
- ??????????
- ????????(這里是將authorityFilter這個類委托給spring來代理)??
- ??????????
- ????-- > ??
- ???? < filter-mapping > ??
- ???????? < filter-name > OpenSessionInViewFilter </ filter-name > ??
- ???????? < url-pattern > /* </ url-pattern > ??
- ???? </ filter-mapping > ??
- ???? < filter-mapping > ??
- ???????? < filter-name > authorizen </ filter-name > ??
- ???????? < url-pattern > *.do </ url-pattern > ??
- ???? </ filter-mapping > ??
- ???? <!--?設置監聽?--> ??
- ???? < listener > ??
- ???????? < listener-class > ??
- ????????????org.springframework.web.context.ContextLoaderListener??
- ???????? </ listener-class > ??
- ???? </ listener > ??
- ????<!--?今天有一個朋友問了我一個問題,他使用的是Hibernate/Spring/Struts架構,配置使用Spring的OpenSessionInView?Filter,但是發現不生效,lazy的集合屬性在頁面訪問的時候仍然報session已經關閉的錯誤。我和他一起檢查了所有的配置和相關的代碼,但是沒有發現任何問題。經過調試發現,應用程序使用的Session和OpenSessionInView?Filter打開的Session不是同一個,所以OpenSessionInView模式沒有生效,但是為什么他們不使用同一個Session呢???
- ??????????
- ????????檢查了一遍Spring的相關源代碼,發現了問題的根源:??
- ??????????
- ????????通常在Web應用中初始化Spring的配置,我們會在web.xml里面配置一個Listener,即:??
- ??????????
- ????????Xml代碼??-- > ??
- ???? < listener > ??
- ???????? < listener-class > ??
- ????????????org.springframework.web.context.ContextLoaderListener??
- ???????? </ listener-class > ??
- ???? </ listener > ??
- ???? <!--?啟動spring的一種模式,運行之后要去找上面的<context-param></context-param>?--> ??
- ???? < listener > ??
- ???????? < listener-class > ??
- ????????????org.springframework.web.context.ContextLoaderListener??
- ???????? </ listener-class > ??
- ???? </ listener > ??
- ??
- ????<!--?如果使用Struts,那么需要在Struts的配置文件struts-config.xml里面配置一個Spring的plugin:ContextLoaderPlugIn。??
- ??????????
- ????????實際上ContextLoaderListener和ContextLoaderPlugIn的功能是重疊的,他們都是進行Spring配置的初始化工作的。因此,如果你不打算使用OpenSessionInView,那么你并不需要在web.xml里面配置ContextLoaderListener。??
- ??????????
- ????????好了,但是你現在既需要Struts集成Spring,又需要OpenSessionInView模式,問題就來了!??
- ??????????
- ????????由于ContextLoaderListener和ContextLoaderPlugIn功能重疊,都是初始化Spring,你不應該進行兩次初始化,所以你不應該同時使用這兩者,只能選擇一個,因為你現在需要集成Struts,所以你只能使用ContextLoaderPlugIn。??
- ??????????
- ????????但是令人困惑的是,ContextLoaderListener和ContextLoaderPlugIn有一個非常矛盾的地方!??
- ??????????
- ????????ContextLoaderListener初始化spring配置,然后把它放在ServletContext對象里面保存:??
- ??????????
- ????????[code:1]servletContext.setAttribute(??
- ????????WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,?this.context);[/code:1]??
- ??????????
- ????????請注意,保存的對象的key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE!??
- ??????????
- ????????但是ContextLoaderPlugIn初始化spring配置,然后把它放在ServletContext對象里面保存:??
- ??????????
- ????????[code:1]??
- ????????String? attrName ?=? getServletContextAttributeName ();??
- ????????getServletContext().setAttribute(attrName,?wac);[/code:1]??
- ??????????
- ????????這個attrName和WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE名字是不一樣的!??
- ??????????
- ????????如果僅僅是名字不一樣,問題還不大,你仍然可以放心使用ContextLoaderPlugIn,但是當你使用OpenSessionInView的時候,OpenSessionInViewFilter是使用哪個key取得spring配置的呢???
- ??????????
- ????????[code:1]WebApplicationContext? wac ?=??
- ???????? WebApplicationContextUtils .getRequiredWebApplicationContext(getServletContext());[/code:1]??
- ??????????
- ????????顯然,OpenSessionInViewFilter是按照WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE這個key去拿spring配置的!??
- ??????????
- ????????我們整理一下思路:??
- ??????????
- ????????ContextLoaderPlugIn保存spring配置的名字叫做attrName;??
- ????????,ContextLoaderListener保存spring配置的名字叫做WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;??
- ????????而OpenSessionInView是按照WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE這個名字去取得spring配置的!??
- ????????而你的應用程序卻是按照attrName去取得spring的配置的!??
- ??????????
- ????????所以,OpenSessionInView模式失效!??
- ??????????
- ????????解決辦法:??
- ????????修改ContextLoaderPlugIn代碼,在getServletContext().setAttribute(attrName,?wac);這個地方加上一行代碼:??
- ????????getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,?wac);??
- ??????????
- ????????或者修改OpenSessionInViewFilter,讓它按照attrName去取得spring配置。??
- ????-- > ??
- ???? <!--?初始頁面?--> ??
- ???? < welcome-file-list > ??
- ???????? < welcome-file > /index.html </ welcome-file > ??
- ???? </ welcome-file-list > ??
- ??
-
</
web-app
>
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
