Skip to content

Интернационализация в Spring

Синопсис

В этом небольшом посте рассмотрим применение интернационализации в спринге.

Готовый проект можно взять с gitHub: https://github.com/dev-blogs/spring подпроект i18n

Структура проекта

  i18n
    ├──src
    │   └──main
    │       ├──java
    │       │   └──com
    │       │       └──devblogs
    │       │           └──App.java
    │       └──resources
    │           ├──spring
    │           │   └──context.xml
    │           ├──labels_en.properties
    │           └──labels_ru_RU.properties
    └──pom.xml

Немного теории

Экземпляр MessageSource можно вытаскивать на прямую, то есть запрашивать его из контекста по лукапу (или автосвязыванием) и вытаскивать из него сообщения через метод getMessage() или вместо бина MessageSource можно использовать сам контекст ApplicationContext, так как интерфейс ApplicationContext реализует интерфейс MessageSource и в нем присутствует метод getMessage(). В случае второго подхода, используя интерфейс ApplicationContext как MessageSource, в самом спринговом контексте нужно определить бин типа MessageSource с именем messageSource. Далее когда будет формироваться объект контекста ApplicationContext бин messageSource будет вложен в контекст ApplicationContext за счет реализации классом ApplicationContext интерфейса HierarchicalMessageSource который позволяет вкладывать друг в друга экземпляры MessageSource.
Метод getMessage() извлекает сообщение с ключом для указанной локали, то есть имя файла свойств состоит из базового имени плюс имя локали, например если файл свойств называется labels_ru_RU.properties, то часть имени labels это базовое имя — прописывается в контексте, а часть имени ru_RU это имя локали — указывается в параметре метода getMessage() и тот файл который нужно искать в каталоге resource состоит из комбинации этих двух частей.
В этом пример применим два подхода, вытащим бин messageSource напрямую из контекста и вызовем метод getMessage() и обратимся к контексту ApplicationContext как к messageSource эффект будет тот же.

Java код

package com.devblogs;

import java.util.Locale;
import org.springframework.context.MessageSource;
import org.springframework.context.support.GenericXmlApplicationContext;

public class App {
	public static void main(String[] args) {
		GenericXmlApplicationContext context = new GenericXmlApplicationContext();
		context.load("classpath:spring/context.xml");
		context.refresh();
		
		Locale english = Locale.ENGLISH;
		Locale russian = new Locale("ru", "RU");
		
		System.out.println("-------------------Получение MessageSource из контекста--------------------------");
		
		System.out.println(context.getMessage("msg", null, english));
		System.out.println(context.getMessage("msg", null, russian));
		
		System.out.println(context.getMessage("nameMsg", new Object[] { "Name1", "Name2"}, english));
		System.out.println(context.getMessage("nameMsg", new Object[] { "Name1", "Name2"}, russian));
		
		//----------Получаем доступ к бину ResourceBundleMessageSource-------------
		System.out.println("---------------------------Лукап ResourceBundleMessageSource-------------------------------");
		
		MessageSource messageSource = (MessageSource) context.getBean("messageSource");
		
		System.out.println(messageSource.getMessage("msg", null, english));
		System.out.println(messageSource.getMessage("msg", null, russian));
		
		System.out.println(messageSource.getMessage("nameMsg", new Object[] { "Name1", "Name2"}, english));
		System.out.println(messageSource.getMessage("nameMsg", new Object[] { "Name1", "Name2"}, russian));
	}
}

Конфигурация

Основы набора имён файлов конфигурируются в конфигурационном файле. Для бина определяемого бина org.springframework.context.support.ResourceBundleMessageSource указываем список базовых имен buttons и labels (строчки 13, 14):

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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    	<property name="basenames">
    		<list>
    			<value>buttons</value>
    			<value>labels</value>
    		</list>
    	</property>
    </bean> 
</beans>

Файлы свойств для русского и английского языков. Часть labels берется из спринговой конфигурации, часть ru_RU берется из параметра в вызове метода getMessage():

labels_ru_RU.properties

msg=Тест
nameMsg=Меня зовут {0} {1}

labels_en.properties

msg=Test
nameMsg=My name is {0} {1}

Сборка и запуск

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.devglogs</groupId>
	<artifactId>i18n</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>i18n</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring.version>3.2.7.RELEASE</spring.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

аутпут

Feb 07, 2017 6:35:57 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring/context.xml]
Feb 07, 2017 6:35:57 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericXmlApplicationContext@4783da3f: startup date [Tue Feb 07 18:35:57 EET 2017]; root of context hierarchy
Feb 07, 2017 6:35:57 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5a39699c: defining beans [messageSource]; root of factory hierarchy
-------------------Получение MessageSource из контекста--------------------------
Feb 07, 2017 6:35:57 PM org.springframework.context.support.ResourceBundleMessageSource getResourceBundle
WARNING: ResourceBundle [buttons] not found for MessageSource: Can't find bundle for base name buttons, locale en
Test
Feb 07, 2017 6:35:57 PM org.springframework.context.support.ResourceBundleMessageSource getResourceBundle
WARNING: ResourceBundle [buttons] not found for MessageSource: Can't find bundle for base name buttons, locale ru_RU
Тест
Feb 07, 2017 6:35:57 PM org.springframework.context.support.ResourceBundleMessageSource getResourceBundle
WARNING: ResourceBundle [buttons] not found for MessageSource: Can't find bundle for base name buttons, locale en
My name is Name1 Name2
Feb 07, 2017 6:35:57 PM org.springframework.context.support.ResourceBundleMessageSource getResourceBundle
WARNING: ResourceBundle [buttons] not found for MessageSource: Can't find bundle for base name buttons, locale ru_RU
Меня зовут Name1 Name2
---------------------------Лукап ResourceBundleMessageSource-------------------------------
Feb 07, 2017 6:35:57 PM org.springframework.context.support.ResourceBundleMessageSource getResourceBundle
WARNING: ResourceBundle [buttons] not found for MessageSource: Can't find bundle for base name buttons, locale en
Test
Feb 07, 2017 6:35:57 PM org.springframework.context.support.ResourceBundleMessageSource getResourceBundle
WARNING: ResourceBundle [buttons] not found for MessageSource: Can't find bundle for base name buttons, locale ru_RU
Тест
Feb 07, 2017 6:35:57 PM org.springframework.context.support.ResourceBundleMessageSource getResourceBundle
WARNING: ResourceBundle [buttons] not found for MessageSource: Can't find bundle for base name buttons, locale en
My name is Name1 Name2
Feb 07, 2017 6:35:57 PM org.springframework.context.support.ResourceBundleMessageSource getResourceBundle
WARNING: ResourceBundle [buttons] not found for MessageSource: Can't find bundle for base name buttons, locale ru_RU
Меня зовут Name1 Name2

Поделиться в социальных сетях

Опубликовать в Google Plus
Опубликовать в LiveJournal
Опубликовать в Мой Мир
Опубликовать в Одноклассники
Опубликовать в Яндекс

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *