Я застрял, возможно, что-то пропустил в документации или сделал небольшую ошибку.
Spring Security 3.0.5 был интегрирован в мое приложение Spring MVC 3.0.5. AcceptHeaderLocaleResolver используется для обнаружения локали, и локализация работает нормально, за исключением сообщений об ошибках безопасности.
Я скопировал messages.properties из пакета безопасности Spring, переименовал и добавил в существующий компонент messageSource (ResourceBundleMessageSource) со списком значений.
Как уже говорилось ранее, все тексты исообщения локализованы правильно, за исключением швов безопасности для использования жестко закодированных сообщений на английском языке.
Есть идеи, как решить эту проблему?
ОБНОВЛЕНИЕ: Мой xy-servlet.xml содержит:
... <mvc:resources mapping="/resources/**" location="/resources/" /> ... <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>defaultMessages</value> <value>securityMessages</value> </list> </property> </bean>
и файлы
defaultMessages.properties
defaultMessages_en.properties
defaultMessages_de.properties
defaultMessages_sl.properties
и
securityMessages.properties
securityMessages_en.properties
securityMessages_de.properties
securityMessages_sl.properties
но defaultMessages работают нормально.securityMessages нет.Я сделал небольшие изменения во всех securityMessages файлах, но они игнорируются и отображаются жестко закодированные сообщения на английском языке.
defaultMessages
securityMessages
ОБНОВЛЕНИЕ v2: Мой dispatcher-servlet.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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:sec="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <context:component-scan base-package="com.example.sampleapp1" /> <context:annotation-config /> <mvc:annotation-driven/> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory --> <mvc:resources mapping="/resources/**" location="/resources/" /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/views/" p:suffix=".jsp" /> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>defaultMessages</value> <value>securityMessages</value> <value>org/springframework/security/messages_de</value> </list> </property> </bean> <!-- Persistence --> <bean id="myPMF" class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean"> <property name="persistenceManagerFactoryName" value="transactions-optional"/> </bean> <!-- Form Validator --> </beans>
Наконец, решение! Бин для сообщений безопасности, очевидно, должен быть объявлен в applicationContext-security.xml и не в контексте приложения xml config ... Я не нашел это нигде в руководстве! В моем случае правильным решением является bean в applicationContext-security.xml:
<b:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <b:property name="basenames"> <b:value>secMessages</b:value> </b:property> </b:bean>
Спасибо @ bluefoot и @ jtoberon за некоторые идеи.
UPDATE: Для правильной работы web.xml должен содержать localizationFilter до springSecurityFilterChain , мой 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"> <!-- The definition of the Root Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/applicationContext-security.xml</param-value> </context-param> <!-- i18n --> <filter> <filter-name>localizationFilter</filter-name> <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> </filter> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <!-- i18n --> <filter-mapping> <filter-name>localizationFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> <!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Проверьте строки после комментариев i18n.
Я не знаю, как вы это сделали (вы не сказали), но чтобы использовать пакет сообщений, который поставляется с пружинной защитой (вместо жестко закодированных текстовых сообщений), я просто должен объявить ResourceBundleMessageSource bean и установите свойство basenames:
ResourceBundleMessageSource
basenames
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>org/springframework/security/messages_pt_BR</value> </list> </property> </bean>
Это изменит сообщения на pt_BR, сделав spring с использованием этого bean-компонента вместо стандартного (не нужно копировать файл куда-то еще, при условии, конечно, что у вас есть jar на вашем classpath).
Вот несколько идей: