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
Комментариев нет:
Отправить комментарий