Java ResourceBundle
July 18, 2019
ResourceBundle
contains locale-specific objects by loading locale-specific resource. ResourceBundle
loads the resource according to current user' locale. This helps the developer to write program independent of user' locale. Using ResourceBundle
, we can optimize our application in different locales easily, handle multiple locales and application can be modified for more locales later. To use ResourceBundle
, our all resources name should contain a base name as prefix and locale as suffix.
ResourceBundle
has two known subclasses i.e. ListResourceBundle
and PropertyResourceBundle
. The ListResourceBundle
works with resource bundle as Java classes and PropertyResourceBundle
works with property files. Both approach has to follow same naming convention i.e. the combination of base name and locale. To get a ResourceBundle
instance, we need to call ResourceBundle.getBundle
method and pass resource base name and locale. To fetch the value for a key from resources, we need to call getObject
, getString
and getStringArray
methods of ResourceBundle
on the instance of ResourceBundle
and pass key as string.
Contents
Naming of Resource Bundles
Resource bundles can be a property file or Java class. The resource bundle names are created by combining a base name and locale. Find the sample examples.1. Property File: Suppose
myapp
is property file base name then we will create resource bundle files as following.
myapp.properties myapp_en_CA.properties myapp_de_DE.properties myapp_fr_FR.properties
Locale
.
a. For default
Locale
the resource file name will be myapp.properties
.
b. For
Locale("en", "CA")
the resource file name will be myapp_en_CA.properties
.
c. For
Locale("de", "DE")
the resource file name will be myapp_de_DE.properties
.
d. For
Locale("fr", "FR")
the resource file name will be myapp_fr_FR.properties
2. Java Class: Resource bundle classes are created as subclasses of
ListResourceBundle
. Suppose MyApp
is base class name, we will create resource bundle classes as following.
MyApp.class MyApp_en_CA.class MyApp_de_DE.class MyApp_fr_FR.class
Locale
.
a. For default
Locale
the resource class name will be MyApp.class
.
b. For
Locale("en", "CA")
the resource class name will be MyApp_en_CA.class
.
c. For
Locale("de", "DE")
the resource class name will be MyApp_de_DE.class
.
d. For
Locale("fr", "FR")
the resource class name will be MyApp_fr_FR.class
Property Files as ResourceBundle
We will create an example ofResourceBundle
using property file with locales en_CA, de_DE, fr_FR and default locale.
1. Create resource bundle property files
myapp.properties
user.name= Enter user name user.pwd= Enter password user.submit= Submit
user.name= Enter user name (CA) user.pwd= Enter password (CA) user.submit= Submit (CA)
user.name= Benutzernamen eingeben user.pwd= Passwort eingeben user.submit= einreichen
user.name= Saisissez votre nom d'utilisateur user.pwd= Entrer le mot de passe user.submit= Soumettre
2. Create
ResourceBundle
and fetch valueTo create
ResourceBundle
, we need to call ResourceBundle.getBundle
method and pass resource base name and locale. In our example resource file base name is myapp
. Find the code.
ResourceBundle rs = ResourceBundle.getBundle("com.concretepage.lsbundles.MyDataBundle", new Locale("de", "DE"));
getObject
, getString
and getStringArray
methods of ResourceBundle
and pass key as string.
String username = rs.getString("user.name"); String password = rs.getString("user.pwd"); String submit = rs.getString("user.submit");
MyApplication.java
package com.concretepage; import java.util.Locale; import java.util.ResourceBundle; public class MyApplication { public static void main(String[] args) { System.out.println("---For Locale de_DE---"); ResourceBundle rs = ResourceBundle.getBundle("myapp", new Locale("de", "DE")); displayPropDetails(rs); System.out.println("---For Locale en_CA---"); rs = ResourceBundle.getBundle("myapp", new Locale("en", "CA")); displayPropDetails(rs); System.out.println("---For Locale fr_FR---"); rs = ResourceBundle.getBundle("myapp", new Locale("fr", "FR")); displayPropDetails(rs); System.out.println("---For Default Locale---"); rs = ResourceBundle.getBundle("myapp", Locale.getDefault()); displayPropDetails(rs); } private static void displayPropDetails(ResourceBundle rs) { String username = rs.getString("user.name"); String password = rs.getString("user.pwd"); String submit = rs.getString("user.submit"); System.out.println(username + " | " + password + " | " + submit); } }
---For Locale de_DE--- Benutzernamen eingeben | Passwort eingeben | einreichen ---For Locale en_CA--- Enter user name (CA) | Enter password (CA) | Submit (CA) ---For Locale fr_FR--- Saisissez votre nom d'utilisateur | Entrer le mot de passe | Soumettre ---For Default Locale--- Enter user name | Enter password | Submit
getKeys()
: We can iterate all the keys using
getKeys()
method of ResourceBundle
and fetch values using the keys.
ResourceBundle rs = ResourceBundle.getBundle("myapp", new Locale("de", "DE")); Enumeration<String> en = rs.getKeys(); while(en.hasMoreElements()){ String key= en.nextElement(); System.out.println("key:"+ key +", Values:"+rs.getString(key)); }
Classes as ResourceBundle
To use classes as resource bundle we need to create subclasses of JavaListResourceBundle
. The ListResourceBundle
is an abstract class of ResourceBundle
that manages resources for a locale. Resources are created as Java classes. To create resource classes, we need to create subclasses of ListResourceBundle
for every required locale and override its getContents()
method.
We will create an example of
ResourceBundle
using Java classes with locales en_CA, de_DE, fr_FR and default locale.
1. Create resource bundle classes
MyApp.java
package com.concretepage.resourcebundle; import java.util.Arrays; import java.util.ListResourceBundle; import com.concretepage.StateHead; public class MyApp extends ListResourceBundle { @Override protected Object[][] getContents() { return contents; } private Object[][] contents = { { "location", "United States" }, { "literacy", Double.valueOf(99.20) }, { "famousCities", Arrays.asList("New York", "Chicago", "Charleston") }, { "stateHead", new StateHead("Donald Trump", 73) } }; }
package com.concretepage.resourcebundle; import java.util.Arrays; import java.util.ListResourceBundle; import com.concretepage.StateHead; public class MyApp_en_CA extends ListResourceBundle { @Override protected Object[][] getContents() { return contents; } private Object[][] contents = { { "location", "Canada" }, { "literacy", Double.valueOf(99.00) }, { "famousCities", Arrays.asList("Toronto", "Vancouver", "Montreal") }, { "stateHead", new StateHead("Justin Trudeau", 47) } }; }
package com.concretepage.resourcebundle; import java.util.Arrays; import java.util.ListResourceBundle; import com.concretepage.StateHead; public class MyApp_de_DE extends ListResourceBundle { @Override protected Object[][] getContents() { return contents; } private Object[][] contents = { { "location", "Germany" }, { "literacy", Double.valueOf(98.40) }, { "famousCities", Arrays.asList("Berlin", "Munich", "Frankfurt") }, { "stateHead", new StateHead("Frank-Walter", 63) } }; }
package com.concretepage.resourcebundle; import java.util.Arrays; import java.util.ListResourceBundle; import com.concretepage.StateHead; public class MyApp_fr_FR extends ListResourceBundle { @Override protected Object[][] getContents() { return contents; } private Object[][] contents = { { "location", "France" }, { "literacy", Double.valueOf(99.50) }, { "famousCities", Arrays.asList("Paris", "Lyon", "Nice") }, { "stateHead", new StateHead("Emmanuel Macron", 41) } }; }
package com.concretepage; public class StateHead { private String name; private int age; public StateHead(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } }
2. Create
ResourceBundle
and fetch value To create
ResourceBundle
, we need to call ResourceBundle.getBundle
method and pass resource base name and locale. Resource class base name is fully qualified class base name. In our example resource class base name is as following.
com.concretepage.resourcebundle.MyApp
ResourceBundle
.
ResourceBundle rs = ResourceBundle.getBundle("com.concretepage.lsbundles.MyDataBundle", new Locale("de", "DE"));
getObject
, getString
and getStringArray
methods of ResourceBundle
and pass key as string. When we call getObject
, it returns object of Object
data type and we can typecast it in our required data type.
String location = rs.getString("location"); Double literacy = (Double)rs.getObject("literacy"); List<?> famousCities = (List<?>) rs.getObject("famousCities"); StateHead stateHead = (StateHead)rs.getObject("stateHead");
MyApplication.java
package com.concretepage; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; public class MyApplication { public static void main(String[] args) { System.out.println("---For Locale de_DE---"); ResourceBundle rs = ResourceBundle.getBundle("com.concretepage.resourcebundle.MyApp", new Locale("de", "DE")); displayDetails(rs); System.out.println("---For Locale en_CA---"); rs = ResourceBundle.getBundle("com.concretepage.resourcebundle.MyApp", new Locale("en", "CA")); displayDetails(rs); System.out.println("---For Locale fr_FR---"); rs = ResourceBundle.getBundle("com.concretepage.resourcebundle.MyApp", new Locale("fr", "FR")); displayDetails(rs); System.out.println("---For Default Locale---"); rs = ResourceBundle.getBundle("com.concretepage.resourcebundle.MyApp", Locale.getDefault()); displayDetails(rs); } private static void displayDetails(ResourceBundle rs) { String location = rs.getString("location"); Double literacy = (Double)rs.getObject("literacy"); List<?> famousCities = (List<?>) rs.getObject("famousCities"); StateHead stateHead = (StateHead)rs.getObject("stateHead"); System.out.println(location); System.out.println(literacy); famousCities.forEach(s -> System.out.print(s + " ")); System.out.println("\n" + stateHead.getName() + "-" + stateHead.getAge()); } }
---For Locale de_DE--- Germany 98.4 Berlin Munich Frankfurt Frank-Walter-63 ---For Locale en_CA--- Canada 99.0 Toronto Vancouver Montreal Justin Trudeau-47 ---For Locale fr_FR--- France 99.5 Paris Lyon Nice Emmanuel Macron-41 ---For Default Locale--- United States 99.2 New York Chicago Charleston Donald Trump-73
References
Class ResourceBundleUsing a ListResourceBundle