简体   繁体   中英

Spring themes and application context

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>

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM