Spring 主题和应用程序上下文

发布于 2024-11-30 11:18:07 字数 9801 浏览 0 评论 0原文

我正在将主题添加到现有的 Spring 3.0.5 项目中。我正在使用 CookieThemeResolver 。虽然我可以加载一个主题,但它不是指定的默认值(如 theResolver bean 中指定的),并且 themeChangeInterceptor 似乎不起作用。

我知道我添加的三个主题配置有效,因为我将它们(以及 CSS 资源)添加到了 spring MVC-basic 项目中。他们工作得很好。此外,Spring mvc-basic 项目不需要 web.xml 中的 ContextLoaderListener,而我的项目则需要。

最初我没有应用程序上下文(我不需要),但是将主题配置添加到我的项目中会导致包含 spring:theme 标记的页面在该页面上出错并抱怨 java.lang.IllegalStateException: No WebApplicationContext found: spring:theme 标签上没有注册 ContextLoaderListener。因此,我添加了一个 ContextLoaderListener 并将 spring mvc-basic 应用程序中不存在的所有内容放入 application-context.xml 中。

由于在 Spring mvc-basic 项目中使用相同的 spring 标签和主题配置不会发生此错误(并且 mvc 项目没有侦听器或上下文参数属性),因此我必须得出结论,现在我的元素中的元素之一应用程序上下文是问题所在。

当我的应用程序在下面的配置中运行时,它会加载 theme.properties 文件(该文件与 theme-day.properties 和 theme-night.properties 一起位于类路径中)。当发出 ?theme=day 或 ?theme=night 请求时,不会设置 cookie。然而,即使我的日志设置打开以进行跟踪,它也不会引发任何错误。

希望有人能够指出 WTF 正在发生。我已将配置配对回最低限度。剩余的一个或多个元素是问题的原因。如果您有疑问,请询问。

我尝试将所有内容移至应用程序上下文中,但这并没有解决问题。我尝试删除元素,但这里发布的元素是最低限度的,不会破坏整个应用程序。重新检查我的 jar 是否有正确的版本以及相同版本的 POM 文件。

更多信息:由于区域设置解析器遵循相同的模式(不需要标签),我从 JSP 中删除了所有主题配置和标签,并将所有声明移回 servlet.xml 并终止了 ContextLoaderListener 及其配置。结果与主题类似,因为 spring 默认值(也称为浏览器区域设置的默认值)可以工作,但无法设置 cookie,并且与区域设置功能相关的其他功能似乎不起作用。将所有内容分解到 application.xml 并将 ContextLoaderListener 放回原处会产生相同的结果。所以至少这是一致的,由于我的配置的某些部分,区域设置和主题都被破坏了。此外,对 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>

application-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>

I am adding themes to an existing Spring 3.0.5 project. I am using the CookieThemeResolver . While I can get a theme to load it is not the specified default( as specified in the theResolver bean) and the themeChangeInterceptor does not appear to be working .

I know the three theme configurations I added work, because I added them (and the CSS resources) to the spring MVC-basic project. They worked fine. Also the Spring mvc-basic project did not require a ContextLoaderListener in web.xml where as my project did.

Originally I did not have an application context (I did not need one) however adding the theme configurations to my project caused the pages containing the spring:theme tags to error on that page and complain of java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered on the spring:theme tag. So I added a ContextLoaderListener and put everthing that is not also in the spring mvc-basic app into the application-context.xml.

Since this error does not occur with the same spring tags and theme configuration in the Spring mvc-basic project ( and the mvc project has no listener or context param attributes ) I have to conclude that one of the elements that are in what is now my application context is the problem.

When my app runs in the configuration below it loads the theme.properties file ( which is in the classpath along with theme-day.properties and theme-night.properties ). no cookies are set when the ?theme=day or ?theme=night requests are made. However it also does not throw any errors even with my log settings turned up to trace.

Hopefully someone will be able to point out WTF is happening . I have paired back the configs to just the bare minimum. One or more of the remaining elements is the cause of the problem. If you have questions please ask.

I have tried moving everything into the application-context, which did not solve the problem. I have tried to remove elements but the ones posted here are the bare minimum without trashing to whole app. On rechecked my jars for the correct versions and POM files for the same versions.

More info : Since the locale resolvers follow the same pattern (without the need for a tag) I removed all the theme configs and tags from the JSP and moved all my declarations back to the servlet.xml and killed the ContextLoaderListener and its config. Result was similar to the themes, in that the spring default (aka default to browser locale) work but no cookie could be set and nothing else regarding the locale functionality seemed to be working. Breaking every back out to application.xml and putting the ContextLoaderListener back in had the same result. So at least this is consistent, both locale AND themes are broken due to some portion of my configuration. Also the need for the ContextLoaderListener is not a direct function of the theme tag but a side effect of one of the other elements.

update 2
I upgraded to 3.0.6 and found the following items while running at the trace level.

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

This line shows up just prior to each view is rendered. It suggests( to me) that the ResourceBundleThemeSource is only operating off its defaults.

    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

This error appears while the application is initializing. Since the exact same configuration works in the MVC-Basic project I am not sure why this is occurring. I understand what it is saying I just don't see what's wrong.

Setup is as follows

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>

application-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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷鸟归林 2024-12-07 11:18:07

解决这个问题。

事实证明,区域设置和主题系统无法应用于 WEB-INF 之外的应用程序元素。

因此,将尝试在应用程序中“松散”的 JSP 上使用区域设置和主题的 spring 标签将会失败。

因此,在上面的代码中,我将所有内容移回到 servlet-context.xml 中。从 index.jsp 文件(位于 web-app 的根目录)中取出我的标签,并将所有内容移回视图中。现在一切正常了。

我希望这对某人有帮助。如果您发现不同请在此发帖

Solution to this problem.

It turns out that the locale and theme system cannot apply to elements of the app outside WEB-INF.

So putting the spring tags attempting to use locale and themes on JSPs that are "loose" in the app will fail.

So in the case of the above code, I moved everything back into the servlet-context.xml., Took my tags out of the index.jsp file ( which is at the root of web-app ) and moved everything back into views. Now it all works .

I hope this helps someone. If you find differently Please post here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文