2011-08-21 67 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的根目录)中取出,并将所有内容回到视图。现在一切正常。

我希望这可以帮助别人。如果您发现不同请张贴在这里