javax.servlet.jsp.tagext.SimpleTagSupport
javax.servlet.jsp.tagext.TagSupport
... ...
的子類.當然在這些子類中訪問Spring的bean也代表著與Spring的框架緊緊聯系在壹起.因為在這些類中無法使用Spring IoC.只能用Spring的:WebApplicationContextUtils.getWebApplicationContext(sc)方法去查找想要的bean.肯定有人會說這樣是不好的!不推薦的.從另壹個方面來說WebApplicationContextUtils.getWebApplicationContext方法肯定有存在的必要.下面是壹個場景:
公***資源
例如社保系統中的險種(養老,醫療,工傷,...).在險種申報,收費,參保中都要用到他.哪就要考慮復用.保存這些資源有很多方式:xml,properties,數據庫.
xml:
可以用單體類.
properties:
可以用單體類,工具類
數據庫:
對於企業級應用(用瀏覽器作表示層).就要考慮在多個jsp頁面中復用.jsp中復用我首選 的就是自定義標簽.這樣可以消滅jsp中的java代碼. 這裏就存在兩種情況:
1.用struts獲取spring管理的bean讀取險種.把壹個列表放到request中,在jsp中把險種列表作為參數傳給自定義標簽.
壹開始我就用此方法.可以用險種列表呈現不同的html tag:可以用select,checkbox. 但後來發現幾乎都是用的同壹種html tag:select.隨即也發現了壹個問題:比如壹個jsp頁面.它只用到了險種列表.但我寫壹個action.所以能不能自定義標簽中獲取險種列表呢.?
2.在自定義標簽中獲取spring管理的bean讀取險種
有了1的經驗.馬上聲明壹個類繼承:SimpleTagSupport.在doTag()方法中用WebApplicationContextUtils.getWebApplicationContext方法獲取spring管理bean,調用bean的方法獲取險種列表.馬上拋出了空指針異常 (NullPointerException).於是有了此貼:
/u/20090902/16/b0400979-11fe-4744-bd84-2e49fb27facd.html
有人說用:WebApplicationContextUtils.getRequiredWebApplicationContext() 方法.雖然spring的參考手冊也推薦用此方法.但這不是這裏的關鍵所 在.這兩個方法在WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 這個鍵值不對應任何對象的時候getWebApplicationContext方法返回null,getRequiredWebApplicationContext() 方法會拋出:IllegalStateException異常
老紫竹說的對.按照他的提示我看了看spring的參考手冊在15.2:通用配置壹節中有壹段話:
all that one need do is to declare a ContextLoaderListener in the standard J2EE servlet web.xml file of one's web application, and add a contextConfigLocation <context-param/> section (in the same file) that defines which set of Spring XML cpnfiguration files to load.
Find below the <listener/> configuration:
[xhtml] view plaincopy
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Find below the <context-param/> configuration:
[xhtml] view plaincopy
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
我就不明白了.要在web.xml中裝載壹個listener.但在struts.xml中我有裝載applicationContext.xml呀:
[xhtml] view plaincopy
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/classes/applicationContext.xml" />
</plug-in>
來看看tomcat的啟動消息吧:
A.以下是web.xml中沒配置org.springframework.web.context.ContextLoaderListener的順序:
...
信息: Starting Servlet Engine: Apache Tomcat/6.0.18
2009-9-8 14:15:57 org.apache.catalina.core.ApplicationContext log
信息: Set web app root system property: 'webapp.root' = [D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/proangle/]
2009-9-8 14:15:57 org.apache.catalina.core.ApplicationContext log
信息: Initializing Log4J from [D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/proangle/WEB-INF/log4j.properties]
2009-9-8 14:15:58 org.apache.catalina.core.ApplicationContext log
信息: Initializing WebApplicationContext for Struts ActionServlet 'action', module ''
2009-9-8 14:16:02 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-8080
...
信息: Server startup in 7744 ms
B.以下是web.xml中配置org.springframework.web.context.ContextLoaderListener的順序:
...
信息: Starting Servlet Engine: Apache Tomcat/6.0.18
2009-9-8 10:16:20 org.apache.catalina.core.ApplicationContext log
信息: Set web app root system property: 'webapp.root' = [D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/proangle/]
2009-9-8 10:16:20 org.apache.catalina.core.ApplicationContext log
信息: Initializing Log4J from [D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/proangle/WEB-INF/log4j.properties]
//----------------------------------------------------------------------
2009-9-8 10:16:21 org.apache.catalina.core.ApplicationContext log
信息: Loading Spring root WebApplicationContext
//----------------------------------------------------------------------