Я добавляю темы в существующий проект Spring 3.0.5. Я использую CookieThemeResolver. Хотя я могу получить тему для загрузки, она не указана по умолчанию (как указано в bean-компоненте Resolver), и themeChangeInterceptor не работает.
Мне известны три конфигурации тем, которые я добавил, потому что я добавил их (и ресурсы CSS) в базовый проект MVC Spring. Они работали нормально. Также для проекта Spring mvc-basic не требовался ContextLoaderListener в web.xml, где, как это делал мой проект.
Изначально у меня не было контекста приложения (он мне не нужен), однако добавление конфигураций темы в мой проект привело к ошибкам на страницах, содержащих теги spring: theme, и жалобе на java.lang.IllegalStateException: Нет Обнаружен WebApplicationContext: нет тега ContextLoaderListener, зарегистрированного в теге spring: theme. Поэтому я добавил ContextLoaderListener и поместил в application-context.xml все, чего нет в весеннем приложении mvc-basic.
Так как эта ошибка не возникает с теми же тегами Spring и конфигурацией темы в проекте Spring mvc-basic (а у проекта mvc нет атрибутов параметров слушателя или контекста), я должен заключить, что один из элементов, которые находятся в сейчас мой прикладной контекст это проблема.
Когда мое приложение запускается в конфигурации ниже, оно загружает файл theme.properties (который находится в пути к классам вместе с theme-day.properties и theme-night.properties). при запросах? theme = day или? theme = night не устанавливаются файлы cookie. Однако, это также не выдает никаких ошибок, даже если мои настройки журнала включены в трассировку.
Надеюсь, кто-то сможет указать, что WTF происходит. Я вернул конфиги к минимуму. Один или несколько из оставшихся элементов является причиной проблемы. Если у вас есть вопросы, пожалуйста, задавайте.
Я пытался переместить все в контекст приложения, что не решило проблему. Я пытался удалить элементы, но те, которые выложены здесь, являются минимальным, не затрагивая все приложение. На перепроверил мои банки для правильных версий и POM-файлов для тех же версий.
Дополнительная информация: Поскольку преобразователи языковых стандартов следуют одному и тому же шаблону (без необходимости тега), я удалил все конфиги и теги темы из JSP и переместил все мои объявления обратно в servlet.xml и уничтожил ContextLoaderListener и его конфигурации. Результат был аналогичен темам в том, что весеннее задание по умолчанию (то есть по умолчанию для локали браузера) работает, но не может быть установлен 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, я не уверен, почему это происходит. Я понимаю, о чем идет речь, я просто не понимаю, в чем дело.
Настройка выглядит следующим образом
сервлет-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>