This tutorial jsf2 internationalization example shows how we make an web based application in different languages. I will show here how we can switch in different languages like Bengali, Hindi, English, Dutch and French. You don’t need to change the language settings from the browser for switching to different languages. I have given user an option to choose a language in a dropdown where the langugaes are displayed in Bengali, Hindi, English, Dutch and French.

If you want you can add more languages and accordingly you need to create separate properties file for each language and configure the supported-locale in faces-config.xml file.

This application shows title, welcome message, choose language option and copyright information in Bengali, Hindi, English, Dutch and French languages. By default the selected language is English. You can also set the default language as per your choice, for that you have to configure in the LocaleSwitcher.java managed bean.

You may also like to read

Spring Boot Internationalization Example

Final output

Choose Language

jsf2 internationalization

Default Language – English

jsf2 internationalization

Language – Bengali

jsf2 internationalization

Language – Hindi

jsf2 internationalization

Language – Nederlands(Dutch)

jsf2 internationalization

Language – French

jsf2 internationalization

So here we go how to create an application step by step.

Prerequisites

JDK 1.6
Eclipse (Netbeans better for creating this kind of project)
Tomcat v7
JSF 2 jar – javax.faces.jar

It is assumed that you have a prior knowledge how to configure jdk, Eclipse and Tomcat server together.

1. First we need to create a Dynamic Web Project in Eclipse. Once you create the Dynamic Web Project, the required project structure gets created. Now put the JSF jar file under WEB-INF/lib directory.

2. We then modify the deployment descriptor file for jsf support and welcome file which gets rendered as home page once the application starts up.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>jsfi18n</display-name>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsf</welcome-file>
</welcome-file-list>
</web-app>

 

In the above web.xml file there are several properties as shown below:

<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>

This context-param tells which environment we will use. Environments can be Development, SystemTest, UnitTest, Extension and Production.

So we will use here Development because we want to get all the benefits for debugging, testing, error reporting etc. for developing the application.

<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

The above configuration uses FacesServlet which is related to Java Server Faces. All requests and responses from the client route through this FacesServlet.

We have also <load-on-startup/> for loading the FacesServlet at the same time when the application starts up.

We can have any value from 0 to 127 for <load-on-startup/>

<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>

We need to map the URL pattern for each request/response coming from the client. We can have *.jsf, *.faces and *.xhtml for <url-pattern/>.

Remember we cannot have multiple URL pattern for JSF application but other application like Struts can have multiple pattern for client requests.

<session-config>
<session-timeout>
30
</session-timeout>
</session-config>

The above configuration is required only if are going to use http session for putting some objects in session like login based application.

<welcome-file-list>
<welcome-file>index.jsf</welcome-file>
</welcome-file-list>

This holds a list of welcome files but remember only one of them will be used – the first one which matches with the URL pattern and file is found in the root directory.

Notice that file extension has .jsf because it should match with the URL pattern otherwise it will give you 404 – page not found.

3. We will create properties files for each language Bengali – Messages_bn.properties

i18n=JSF 2.2 এ আন্তর্জাতিকায়ন উদাহরণ
welcome=বাংলা ভাষা স্বাগতম
chooseLang=আপনার ভাষা চয়ন করুন
copyright=কপিরাইট
2014=2014

Hindi – Messages_hi.properties

i18n=JSF 2.2 में अंतर्राष्ट्रीयकरण उदाहरण
welcome=हिन्दी भाषा में आपका स्वागत है
chooseLang=अपनी भाषा चुनें
copyright=सर्वाधिकार
2014=2014

English – Messages.properties

i18n=Internationalization Example in JSF 2.2
welcome=Welcome to English Language
chooseLang=Choose your language
copyright=Copyright
2014=2014

Dutch – Messages_nl.properties

i18n=Internationalisering Voorbeeld in JSF 2.2
welcome=Welkom bij Nederlandse Taal
chooseLang=Kies uw taal
copyright=Auteursrecht
2014=2014

French – Messages_fr.properties

i18n=Internationalisation exemple dans JSF 2.2
welcome=Bienvenue à la langue française
chooseLang=Choisissez votre langue
copyright=Droit d'auteur
2014=2014

4. Now look at the below JSF Managed Bean LocaleSwitcher.java

package in.webtuts.mbeans;

import java.io.Serializable;
import java.util.Locale;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;

/**
*
* @author https://www.jeejava.com
*/
@ManagedBean
@ViewScoped
public class LocaleSwitcher implements Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;

/**
* Creates a new instance of LocaleSwitcher
*/
public LocaleSwitcher() {
}

//default language - english(en)
private String language = "en";
//get the current locale from facescontext
private Locale locale = FacesContext.getCurrentInstance().getViewRoot()
.getLocale();

public Locale getLocale() {
return locale;
}

public void setLocale(Locale locale) {
this.locale = locale;
}

public String getLanguage() {
return language;
}

public void setLanguage(String language) {
this.language = language;
}

//when dropdown value gets changed - so the language and locale
public void onLanguageChange(ValueChangeEvent vce) {
if (vce != null) {
String l = vce.getNewValue().toString();
setLanguage(l);
locale = new Locale(l);
FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
} else {
FacesContext.getCurrentInstance().getViewRoot()
.setLocale(Locale.ENGLISH);
}
}
}

5. Create face-config.xml file and put it under WEB-INF with the below source code

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

<application>
<!-- locale configuration -->
<locale-config>
<!-- default locale and supported locales -->
<default-locale>en</default-locale>
<supported-locale>bn</supported-locale>
<supported-locale>hi</supported-locale>
<supported-locale>nl</supported-locale>
<supported-locale>fr</supported-locale>
</locale-config>
<!-- resource bundle configuration -->
<resource-bundle>
<!-- properties file base name with full package -->
<base-name>
in.webtuts.i18n.messages.Messages
</base-name>
<!-- properties file key will be accessed using this variable #{msg.keyName}, where keyName is the property file key -->
<var>msg</var>
</resource-bundle>
</application>
</faces-config>

6. We will use template so that we don’t need to copy common things like header/footer and most importantly here is <f:view locale=””/> tag in every page.

So put the template file under WEB-INF/template so that it cannot be tempered from outside the world.

Netbeans has better support for template file generation.

main.xhtml

Look at the below template file with <ui:insert/> tag whose content can be overridden by template client file.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
lang="#{localeSwitcher.language}">

<!-- look below tag how page is viewed in different languages -->
<f:view locale="#{localeSwitcher.locale}">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<h:outputStylesheet name="./css/default.css" />
<h:outputStylesheet name="./css/cssLayout.css" />
<!-- you can override title in template client file. you can put here default title so that if you do not put any title in the template client file then this default title will be used -->
<title><ui:insert name="title" /></title>
</h:head>

<h:body>

<div id="top">
<!-- header part -->
<ui:insert name="top">
<!-- include the header file if header part common for all pages -->
<ui:include src="header.xhtml" />
</ui:insert>
</div>

<!-- body content of the page -->
<div id="content" class="center_content">
<!-- override any default content here in the template client file -->
<ui:insert name="content"></ui:insert>
</div>

<!-- footer part -->
<div id="bottom">
<ui:insert name="bottom">
<!-- include the footer file if footer part common for all pages -->
<ui:include src="footer.xhtml" />
</ui:insert>
</div>

</h:body>
</f:view>

</html>

header.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<body>
<ui:composition>
<h:form prependId="false">
<h:panelGrid columns="3">
<!-- look this is how the key/value pair is being accessed and displayed in different languages -->
<h:outputText value="#{msg.i18n}" />
<h:outputLabel>&nbsp;|&nbsp;</h:outputLabel>
<h:panelGroup>
<!-- look this is how the key/value pair is being accessed and displayed in different languages -->
<h:outputText value="#{msg.chooseLang}" />
<h:selectOneMenu value="#{localeSwitcher.language}"
<!-- whenever a user chooses a language then propagate that value to everywhere -->
onchange="submit()" style="margin-left:5px;"
<!-- get the new language in Managed Bean -->
valueChangeListener="#{localeSwitcher.onLanguageChange}">
<!-- dropdown option values -->
<f:selectItem itemValue="bn" itemLabel="বাংলা" />
<f:selectItem itemValue="hi" itemLabel="हिंदी" />
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="nl" itemLabel="Nederlands" />
<f:selectItem itemValue="fr" itemLabel="Français" />
</h:selectOneMenu>
</h:panelGroup>
</h:panelGrid>
</h:form>
</ui:composition>
</body>
</html>

footer.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<body>
<ui:composition>
<p style="text-align: left;width: 100%;">
<!-- look this is how the key/value pair is being accessed and displayed in different languages -->
<h:outputText value="#{msg.copyright} &copy; 2014" escape="false"/>
</p>
</ui:composition>
</body>
</html>

7. Now we will look into the index.xhtml file. This is a template client file. Netbeans has better support for template client file generation.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<body>

<!-- include the template file -->
<ui:composition template="./WEB-INF/template/main.xhtml">

<!-- override the default title if any in main.xhtml -->
<ui:define name="title">
<!-- look this is how the key/value pair is being accessed and displayed in different languages -->
#{msg.i18n}
</ui:define>

<!-- override the content if any in man.xhtml -->
<ui:define name="content">
<!-- look this is how the key/value pair is being accessed and displayed in different languages -->
<h:outputText value="#{msg.welcome}"></h:outputText>
</ui:define>

</ui:composition>

</body>
</html>

8. Simple css styling under resources/css directory. These css files are automatically generated by Netbeans cssLayout.css

#top {
position: relative;
background-color: #036fab;
color: white;
padding: 5px;
margin: 0px 0px 10px 0px;
}

#bottom {
position: relative;
background-color: #c2dfef;
padding: 5px;
margin: 10px 0px 0px 0px;
}

#left {
float: left;
background-color: #ece3a5;
padding: 5px;
width: 150px;
}

#right {
float: right;
background-color: #ece3a5;
padding: 5px;
width: 150px;
}

.center_content {
position: relative;
background-color: #dddddd;
padding: 5px;
}

.left_content {
background-color: #dddddd;
padding: 5px;
margin-left: 170px;
}

.right_content {
background-color: #dddddd;
padding: 5px;
margin: 0px 170px 0px 170px;
}

#top a:link, #top a:visited {
color: white;
font-weight : bold;
text-decoration: none;
}

#top a:link:hover, #top a:visited:hover {
color: black;
font-weight : bold;
text-decoration : underline;
}

default.css

body {
background-color: #ffffff;
font-size: 12px;
font-family: Verdana, "Verdana CE", Arial, "Arial CE", "Lucida Grande CE", lucida, "Helvetica CE", sans-serif;
color: #000000;
margin: 10px;
}

h1 {
font-family: Arial, "Arial CE", "Lucida Grande CE", lucida, "Helvetica CE", sans-serif;
border-bottom: 1px solid #AFAFAF;
font-size: 16px;
font-weight: bold;
margin: 0px;
padding: 0px;
color: #D20005;
}

a:link, a:visited {
color: #045491;
font-weight : bold;
text-decoration: none;
}

a:link:hover, a:visited:hover {
color: #045491;
font-weight : bold;
text-decoration : underline;
}

That’s all. Thanks for your reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit

0 thoughts on “JSF2 Internationalization example

Leave a Reply

Your email address will not be published. Required fields are marked *