Friday, October 28, 2022

Spring - Internationalization (I18N)

  • Designing java applications w.r.t Local Users is called Internationalization.

  • To provide Internationalization services to the users, first, we have to decide all the users into groups as per locality, for this, we have to use the following parameters.

    • 1. Language: 
      • It able to represent two lower case letters. EX: en, it, hi, .....
    • 2. Country: 
      • It will be represented in the form of two Upper case letters. EX: US, IN, IT,......
    • 3. System Varient[OS]:
      • It will be represented in the form of three lower case letters. EX: win, uni, lin,.....
  • In java applications, to represent a group of local users JAVA has provided a predefined class in the form of "java.util.Locale".
  • To create a Locale class object we have to use the following Constructors.
    • public Locale(String lang)
    • public Locale(String lang, String country)
    • public Locale(String lang, String country, String sys_Varient)

Example:

Locale l1=new Locale("en");
Locale l2=new Locale("en", "US"); 
Locale l3=new Locale("en", "US", "win");

  • In Java applications, we are able to provide the following services as part of Internationalization.

    1. Number Formations
    2. Date Formations 3.Message Formations
    3. Number Formations:
1. Number Formations:

  • It can be used to represent a number w.r.t a particular Locale. It will use java.text.NumberFormat class to represent a number.

  • Steps:
    1. Create Locale object.
    2. Create NumberFormat class object by using the getInstance() Factory method. 
    3. Represent Number as per the Locale by using the format(-) method.

2.Date Formations:

  • It can be used to represent a Date w.r.t a particular Locale, for this, it will use java.text.DateFormat class.

  • Steps:
    1. Create Locale object.
    2. Create DateFormat class object by using getDateInstance(--) Factory
    3. Represent Date w.r.t the Locale by using format(--) method.

3.Message Formations:

  • It can be used to represent messages w.r.t a particular Locale, for this, we have to use properties files and java.util.ResourceBundle class.

  • Steps:

    • Create properties files with all the messages in the form of key-value pairs. Note: properties file names must be provided in the following format. 
      • baseName_lang_country.properties

    • Create ResourceBundle object by using getBundle(--) Factory method. c)Get Message from ResourceBundle object by using getString(-) method.

Example:

com/cloud/resources/abc_en_US.properties 
welcome = Welcome To en US Users.
com/cloud/resources/abc_it_IT.properties
welcome = Welcome To it IT Users.

Test.java

package com.cloud;
import java.text.DateFormat; 
import java.text.NumberFormat; 
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle; 

public class Test {
	public static void main(String[] args)throws Exception { 
		Locale l = new Locale("it", "IT");
		
		NumberFormat num_Format = NumberFormat.getInstance(l); 
		System.out.println(num_Format.format(1234567.23456));
	
		DateFormat date_Format = DateFormat.getDateInstance(0, l); 
		System.out.println(date_Format.format(new Date()));
		
		ResourceBundle resource_Bundle = ResourceBundle.getBundle("com/cloud/resources/abc", l);
		System.out.println(resource_Bundle.getString("welcome")); }
}

  • To provide Message formations in Spring applications, Spring has provided a predefined interface in the form of "org.springframework.context.MessageSource" .
  • For MessageSource interface Spring Framework has provided the following two implementation classes.

org.springframework.context.support.ResourceBundleMessageSource
org.springframework.context.support.ReloadableResourceBundleMessageSource

  • Where ResourceBundleMessageSource is able to get messages from properties files on the basis of the provided locale.
  • Where ReloadableResourceBundleMessageSource is able to get messages from both properties files and from XML files.

Steps:

  • Declare properties files with the messages and with the following format for properties files names.
    • baseName_lang_Country.properties.

  • Declare a Bean class with MessageSource type property and the respective setter method and the required business methods.

  • To get a message from the MessageSource object we have to use the following method.
    • public String getMessage(String key, Object[] place_holder_values, Locale l)

    • Where "key" is key of the message defined in the properties file.

    • Where "Object[] " must be provided to provide values to the place holders which we defined in messages in properties files, if place holders do not exist in messages then we have to provide "null" value as Object[].

    • Where Locale is able to represent the constants like US, FRANCE, IN,... from the Locale class in order to recognize the properties file.

  • Configure bean class in properties file and inject either ResourceBundleMessageSource or ReloadableResourceBundleMessageSource object as a reference in Bean object and provide base name as property for the MessageSource object.

  • In Main class, in main(), get Bean object and access the business method.

Example:

abc_en_US.properties

welcome = Welcome To {0} and {1} User.

abc_fr_FR.properties

welcome = Welcome To {0} and {1} Users.

I18NBean.java

package com.cloud.beans;
import java.util.Locale;
import org.springframework.context.MessageSource;

public class I18NBean {

	private MessageSource messageSource;
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource; }
		
		public void displayMessage(){
			System.out.println("Message :"+messageSource.getMessage("welcome", new
			Object[]{"fr", "FRANCE"}, Locale.FRANCE));
			System.out.println("Message :"+messageSource.getMessage("welcome", new
			Object[]{"en", "US"}, Locale.US));

		}
 	}
 }

applicationContext.xml

<beans>
	<bean id="i18nBean" class="com.cloud.beans.I18NBean">
		<property name="messageSource" ref="resourceBundleMessageSource"/> 
	</bean>
	<bean id="resourceBundleMessageSource" 
		class="org.springframework.context.support.ResourceBundleMessageSource">
		<property name="basename" value="com/cloud/resources/abc"/> 
	</bean>
</beans>

Test.java

package com.cloud.test;
import com.cloud.beans.I18NBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
	public static void main(String[] args)throws Exception {
		ApplicationContext context=
			new ClassPathXmlApplicationContext("applicationContext.xml");
		I18NBean bean = (I18NBean)context.getBean("i18nBean");
		bean.displayMessage(); 
	}
}

  • If we want to take messages from xml file by using ReloadableResourceBundleMessageSource then we have to use define xml files with the name like baseName_lang_Country.xml and with the following tags to represent messages.

<properties>
	<entry key="message_Key"> Message_Value </entry>
</properties>

  • In XML files we must provide the following DTD definition.
  • <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

Example:

abc_en_US.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> 
<properties>
	<entry key="welcome"> Welcome to en US User from XML </entry> 
</properties>

abc_fr_FR.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> 
<properties>
	<entry key="welcome"> Welcome to fr France User from XML </entry> 
</properties>

spring_beans_config.xml

<beans>
	<bean id="i18nBean" class="com.cloud.beans.I18NBean"> 
		<property name="messageSource"
			ref="reloadableResourceBundleMessageSource"/> 
	</bean>

	<bean id="reloadableResourceBundleMessageSource"
		class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
		<property name="basename" value="com/cloud/resources_xml/abc"/>
	</bean>
</beans>

I18NBean.java

package com.cloud.beans;
import java.util.Locale;
import org.springframework.context.MessageSource;

public class I18NBean {

	private MessageSource messageSource;
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}
	public void displayMessage(){
		System.out.println("Message :
			"+messageSource.getMessage("welcome", null, Locale.FRANCE));
		System.out.println("Message :
			"+messageSource.getMessage("welcome", null, Locale.US))
	} 
}

Test.java

package com.cloud.test;

import com.cloud.beans.I18NBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class Test {
	public static void main(String[] args)throws Exception { 

		ApplicationContext context=new
		ClassPathXmlApplicationContext("applicationContext.xml");
		I18NBean bean = (I18NBean)context.getBean("i18nBean");
		bean.displayMessage(); 
	}
}

You may also like

Kubernetes Microservices
Python AI/ML
Spring Framework Spring Boot
Core Java Java Coding Question
Maven AWS