2011-08-21 69 views
0

我添加主題到現有的春天3.0.5項目。我正在使用CookieThemeResolver。雖然我可以獲取要加載的主題,但它不是指定的默認值(如theResolver bean中指定的),並且themeChangeInterceptor似乎不工作。春天的主題和應用程序上下文

我知道這三個主題的配置我添加的工作,因爲我他們(和CSS資源),再加上彈簧MVC的基礎工程。他們工作得很好。另外Spring mvc-basic項目不需要web.xml中的ContextLoaderListener,就像我的項目一樣。

最初我沒有應用程序上下文(我不需要一個),但是將主題配置添加到我的項目中導致包含spring:theme標籤的頁面在該頁面上出錯,並且抱怨java.lang.IllegalStateException:沒有找到WebApplicationContext:沒有ContextLoaderListener在spring:theme標籤上註冊。所以我添加了一個ContextLoaderListener,並將不在spring mvc-basic應用中的everthing放到application-context.xml中。

由於Spring mvc-basic項目中的相同spring標籤和主題配置(並且mvc項目沒有偵聽器或上下文參數屬性)中不會出現此錯誤,所以我必須得出結論,其中一個元素現在我的應用程序上下文是什麼問題。

當我的應用程序的配置下它加載theme.properties文件(這是在類路徑theme-day.properties和theme-night.properties一起)運行。當?theme = day或?theme =夜間請求時,不會設置cookie。但是,即使我的日誌設置已打開以進行跟蹤,它也不會引發任何錯誤。

希望有人能夠指出WTF正在發生的事情。我已經將配置恢復到最低限度。其餘一個或多個元素是問題的原因。如果您有問題,請詢問。

我已經試過一切移動到應用程序上下文,它並沒有解決問題。我試圖刪除元素,但這裏發佈的元素是最低限度的,而不會摧毀整個應用程序。重新檢查我的罐子是否有相同版本的正確版本和POM文件。

更多信息:由於本地化解析器遵循相同的模式(無需標籤)我刪除從JSP中的所有主題CONFIGS和標籤,並動了我的所有聲明回servlet.xml中,殺死了的ContextLoaderListener和它的配置。結果與主題相似,因爲春天的默認設置(也就是默認爲瀏覽器語言環境)可以工作,但不能設置cookie,並且沒有任何有關語言環境功能的其他功能似乎正在工作。將所有內容重新分配給application.xml,並將ContextLoaderListener放回原來的結果。所以至少這是一致的,由於我的配置的某些部分,locale和主題都被破壞了。此外,對ContextLoaderListener的需求不是主題標籤的直接功能,而是其他元素之一的副作用。

更新2 我升級到3.0.6並在跟蹤級別運行時發現下列項目。

DEBUG ResourceBundleThemeSource,"http-bio-8080"-exec-5: 109 - Theme created: name 'theme',basename [theme] 

此行在每個視圖呈現之前顯示。它表明(對我而言)ResourceBundleThemeSource僅在默認情況下運行。

TRACE DefaultListableBeanFactory,Thread-7:201 Ignoring Constructor [public.org.springframework.web.servlet.handler.MappedInterceptor(java.lang.String[],org.springframework.web.context.request.WebRequestInterceptor)] of bean 'org.springframework.web.servlet.handler.MappedInterceptor#1' :org.springframework.beans.factoryUnsatisfiedDependancyException: Error creating bean with name 'org.springframework.web.servlet.handler.MappedInterceptor#1':Unsatisfied dependnacy expressed through contructor argument with index 1 of type [org.springframework.web.context.request.WebRequestInterceptor]: Could not convert constructor argument value of type [org.springframework.web.servlet.theme.ThemeChangeInterceptor] to required type [org.springframeworkweb.context.request.WebRequestInterceptor]: Failed to convert value of type 'org.springframework.web.servlet.theme.ThemeChangeInterceptor' to required type 'org.springframeworkweb.context.request.WebRequestInterceptor';nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.web.servlet.theme.ThemeChangeInterceptor] to required type [org.springframeworkweb.context.request.WebRequestInterceptor]: no matching editors or conversion strategy found 

當應用程序初始化時出現此錯誤。由於完全相同的配置在MVC-Basic項目中起作用,我不確定爲什麼會發生這種情況。我明白這是什麼意思,我只是沒有看到有什麼問題。

設置是如下

servlet的context.xml中

<?xml version="1.0" encoding="UTF-8"?> 
    <beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:http-conf="http://cxf.apache.org/transports/http/configuration" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
      http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd"> 

<!-- Scans the classpath of this application for @Components to deploy as beans --> 
<context:component-scan base-package="org.myproject.test" /> 

<!-- Configures the @Controller programming model --> 
<mvc:annotation-driven /> 

<!-- Configures Handler Interceptors -->  
<mvc:interceptors> 
    <!-- Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de --> 
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" /> 

    <bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"> 
     <property name="paramName" value="theme" /> 
    </bean> 
</mvc:interceptors> 

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory --> 
<mvc:resources mapping="/resources/**" location="/resources/" /> 

<!-- Saves a locale change using a cookie --> 
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" /> 

<!-- Application Message Bundle --> 
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
    <property name="basename" value="/WEB-INF/messages/messages" /> 
    <property name="cacheSeconds" value="0" /> 
</bean> 

<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory --> 
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="prefix" value="/WEB-INF/views/"/> 
    <property name="suffix" value=".jsp"/> 
</bean> 
    <!-- Theme source and Resolver definition --> 

<bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource"> 
    <property name="basenamePrefix" value="theme-" /> 
</bean> 

<bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver"> 
    <property name="defaultThemeName" value="day" /> 
</bean> 

    </beans> 

應用的context.xml

<?xml version="1.0" encoding="UTF-8"?> 
    <beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.springframework.org/schema/mvc  http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> 

    <!--  Read the config.properties file--> 
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="locations"> 
     <list> 
      <value>classpath:config.properties</value> 
     </list> 
    </property> 
</bean> 

<bean id="myService" class="com.stuff.generated.service1"> 
    <constructor-arg value="${service1UrlPrefix}?wsdl"/> 
</bean> 

<bean id="myServiceFactory" factory-bean="myService1" factory-method="getServicePort"/> 

<bean id="myOtherService" class="com.stuff.generated.service2"> 
    <constructor-arg value="${service2UrlPrefix}?wsdl"/> 
</bean> 
<bean id="myOtherServiceFactory" factory-bean="myService2" factory-method="getServicePort2"/> 

    <!-- assembles some variables used widely which are autowired into other classes 
    contains getter and setters and some code running in afterPropertiesSet() method --> 
    <bean id="myStartVars" class="com.myClass.myStartVars"/> 

    <bean id="autowiredAnnotationBeanPostProcessor" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> 

的web.xml

 <?xml version="1.0" encoding="UTF-8"?> 
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
<!-- Reads request input using UTF-8 encoding --> 
<filter> 
    <filter-name>characterEncodingFilter</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> 
    <init-param> 
     <param-name>forceEncoding</param-name> 
     <param-value>true</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>characterEncodingFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
<!-- Handles all requests into the application --> 
<servlet> 
    <servlet-name>myTest Servlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> /WEB-INF/spring/servlet-context.xml </param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>myTest Servlet</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 

<listener> 
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/spring/application-context.xml</param-value> 
</context-param> 

+0

,我不知道你的意思是「我沒有一個應用程序上下文(我並不需要一個)」,因爲每個Spring應用程序有一個應用程序上下文。僅供參考,元素適用於整個Web應用程序,而contextConfigLocation特別適用於一個servlet。我首先將這些配置文件合併爲一個(無所謂),以確保沒有奇怪的交互。另外,你真的發佈了錯誤發生時使用的最小配置文件嗎? XML似乎不是有效的。 – jtoberon

+0

從春季的例子中可以看出,只有一個servlet context的應用程序纔有可能.Spring然後推動它。它在文檔中。最初他們在一個文件servlet-conext.xml中,我不得不爲一個未知的原因創建一個應用程序上下文。我說未知是因爲我能夠將主題標籤和配置添加到spring mvc basic中,並且它僅在servlet上下文中運行良好。是的,這些是我剪切和粘貼的真實文件。堆棧溢出解釋器與註釋的外觀混在一起,但它看起來像所有的部分在那裏 – stimpy

+1

我的錯誤,XML是有效的。我做的下一件事就是在Spring代碼中的各個點放斷點,如ResourceBundleThemeSource所需和CookieThemeResolver,要理解的行爲,等等。然後,在開始你的應用程序在這些類中的方法的構造調試器並查看真正發生了什麼 - 這些類是如何實例化的等等。或者,另一種方法是更多地刪除應用程序(可以這樣做),以便它除了測試主題或區域設置外不會執行任何操作。一旦你有這個工作,一塊一塊地添加功能。 – jtoberon

回答

0

解決這個問題。

事實證明,語言環境和主題系統不能適用於WEB-INF之外的應用程序的元素。

因此將嘗試使用區域和主題上是「鬆散」的應用程序將失敗的JSP春天標籤。

因此,在上述代碼的情況下,我把所有東西都移回到servlet-context.xml中,將我的標籤從index.jsp文件(位於web-app的根目錄)中取出,並將所有內容回到視圖。現在一切正常。

我希望這可以幫助別人。如果您發現不同請張貼在這裏