Spring mvс и Internationalization (I18N).
Для работы I18N в нашем Spring mvс приложении нужно правильно сконфигурировать компоненты которые отвечают за работу с локалью и интернациональными сообщениями, так называемыми файлами BundleMessage.properties. Для этого нам нужно настроить интерфейс org.springframework.context.MessageSource который позволяет нам работать с I18N файлами в зависимости от установленой локали. Определить текущую локаль запроса нам помогает интерфейс org.springframework.web.servlet.LocaleResolver, а изменять org.springframework.web.servlet.i18n.LocaleChangeInterceptor. Все что нужно запомнить 1-й интерфейс отвечает за место где хранятся файлы ресурсов, 2-й где хранится локаль пользователя, 3-й отвечает за смену локали. Давайте расмотрим все по порядку.
Нам нужны 2 файла Application.properties c данными:
Нам нужны 2 файла Application.properties c данными:
Button.text=Click me english
и Application_ru_RU.properties:
Button.text=Click me По русски!
в зависимости от локали мы будем использовать тот или иной файл для вывода сообщений.
За пути где лежат файлы ответственнен класс ReloadableResourceBundleMessageSource
который наследуется от интерфейса MessageSource:
<beans:bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource" p:basenames="WEB-INF/i18n/Application" p:fallbackToSystemLocale="false" p:fileEncodings="UTF8" p:defaultEncoding="UTF8" />
обратите внимание на параметры p:basenames="WEB-INF/i18n/Application" - указывает
путь где нужно искать наши porperties файлы, p:fileEncodings="UTF8" p:defaultEncoding="UTF8"
указываем что исходная кодировка наших porperties файлов UTF8.
И так перейдем к следующему интерфейсу - LocaleResolver который ответственен за установку
Locale отображаемой страницы, есть несколько класов которые реализуют этот
интерфейс и соответсвенно их можно использовать в настройке Spring контекста
web приложения, давайте расмотрим их - как они реализуют смену и установку
Locale. Первый из них AcceptHeaderLocaleResolver - он берет свою Locale из
заголовка HTTP Header Accept-Language, как мы знаем обычно этот заголовок устанавливается браузером клиента и изменить его программно нельзя, используется поумолчанию:
<beans:bean class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" id="localeResolver" />
Второй это CookieLocaleResolver использует для хранения Locale технологию Cookie, соответственно можно задать имя переменной Cookie, в нашем случае в p:cookieName="localeUser" будет храниться наша Locale и каждый пользователь может переустановить его на свое усмотрение.
<beans:bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" id="localeResolver" p:cookieName="localeUser" p:defaultLocale="en_US"/>
Если в Cookie нет установленного localeUser параметра то берется по умолчанию default значение p:defaultLocale="en_US" иначе используется Locale из заголовка HTTP Header Accept-Language. Следующий FixedLocaleResolver устанавливает фиксированную Locale на все время жизни web приложения параметр p:defaultLocale="en_US", в дальнейшем параметр не может изменяться программно.
<beans:bean class="org.springframework.web.servlet.i18n.FixedLocaleResolver" id="localeResolver" p:defaultLocale="en_US"/>
И последний SessionLocaleResolver хранит Locale в сессии программы (HttpSession)если нет сохраненного значения в сессии то берется по умолчанию default значение p:defaultLocale="en_US" а если не установлено p:defaultLocale то используется Locale из заголовка HTTP Header Accept-Language. Программно может меняться.
<beans:bean class="org.springframework.web.servlet.i18n.SessionLocaleResolver" id="localeResolver" p:defaultLocale="en_US"/>
И напоследок хочу упомянуть интерфейс который позволяет нам менять мокаль программно LocaleChangeInterceptor:
<interceptors> <beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/> </interceptors>
что бы сменить локаль нам нужно только отослать переменную lang c нужной локалью например ru_RU на http://localhost:8080/phone/spring/?lang=ru_RU название переменной настраивается параметром p:paramName="lang".
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" 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"> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <annotation-driven /> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <resources mapping="/resources/**" location="/resources/" /> <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> <beans:property name="contentType" value="text/html;charset=UTF-8"/> </beans:bean> <!-- Imports user-defined @Controller beans that process client requests --> <beans:import resource="controllers.xml" /> <beans:bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource" p:basenames="WEB-INF/i18n/Application" p:fallbackToSystemLocale="false" p:fileEncodings="UTF8" p:defaultEncoding="UTF8" /> <!-- 1 --> <!--<beans:bean class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" id="localeResolver" />--> <!-- 2 --> <!--<beans:bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" id="localeResolver" p:cookieName="localeUser" p:defaultLocale="en_US"/> --> <!-- 3 --> <!--<beans:bean class="org.springframework.web.servlet.i18n.FixedLocaleResolver" id="localeResolver" p:defaultLocale="en_US"/>--> <!-- 4 --> <beans:bean class="org.springframework.web.servlet.i18n.SessionLocaleResolver" id="localeResolver" p:defaultLocale="en_US"/> <interceptors> <beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/> </interceptors> </beans:beans>
Если вы используете для отображения страницы jsp то вы должны использовать Spring Tag Library для работы с internationalization (I18N), для этого вам необходимо в начало страницы добавить <%@ taglib uri="http://www.springframework.org/tags" prefix="msg" %> в нашем случае мы создаем переменную и присваиваем ей значение Button.text выводим значение переменной ${text}
<%@ page contentType="text/html;charset=UTF-8"%> <%@ page pageEncoding="UTF-8" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://www.springframework.org/tags" prefix="msg" %> <%@ page session="false" %> <html> <head> <title>Home</title> </head> <body> <h1> Hello world! </h1> <msg:message code="Button.text" var="test"/> ${test} <br/> ${pageContext.response.locale} <br/> ${controllerMessage} </body> </html>
и на последок обязательно нужно следить за локализацией всего web приложения от начала и до конца все файлы, все ресурсы, все запросы, в моем приложении по умолчанию используют кодировку UTF-8:
Первое все символы в запросе и ответе UTF-8
Первое все символы в запросе и ответе UTF-8
<!-- Creates the Spring Container shared by all Servlets and Filters --> <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>
Второе все файлы набраны в кодировке UTF-8. Третье в jsp файле установлены заголовки
<%@ page contentType="text/html;charset=UTF-8"%> <%@ page pageEncoding="UTF-8" %>
... <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <head>
в четвертых на правильную кодировку настроен contentType класса InternalResourceViewResolver
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/"/> <beans:property name="suffix" value=".jsp"/> <beans:property name="contentType" value="text/html;charset=UTF-8"/> </beans:bean>
в пятых правильно настроен p:fileEncodings и p:defaultEncoding класса ReloadableResourceBundleMessageSource
<beans:bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource" p:basenames="WEB-INF/i18n/Application" p:fallbackToSystemLocale="false" p:fileEncodings="UTF8" p:defaultEncoding="UTF8" />
в шестых использую maven для компиляции приложения, у него настроена кодировка при сборке на UTF-8
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> <encoding>UTF-8</encoding> </configuration> </plugin>
и в седьмых если использую tomcat то настраиваю Connector параметром URIEncoding="UTF-8"
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
если использую подключение к БД настраиваю передачу и хранение данных в нужной кодировке. И так локализация приложения это комплексное действие при котором нужно настраивать всЁ приложение на работу с определенной кодировкой, в моем случае используется - UTF-8.
source code
source code
Комментариев нет:
Отправить комментарий