Struts 2 – i18n or localization example

A Struts 2 internationalizing(i18n), localization(i10n) or multi-lingua example to show the use of resource bundle to display the message from different languages. In this example, you will create a simple login screen, display the message from resource bundle via the Struts 2 UI components, and change the locale base on the selected language option.

1. Project Structure

The project structure for this example

Struts2 localization folder structure

2. Properties file

Make sure the properties file are named as country specified code.

In some “non-Europe” or “non-English” like characters, you should always encode the content with native2ascii tool.

global.properties


#Global messages
global.username = Username
global.password = Password
global.submit = Submit

global_zh_CN.properties


#Global messages
global.username = \u7528\u6237\u540d
global.password = \u5bc6\u7801
global.submit=\u63d0\u4ea4

global_fr.properties


#Global messages
global.username = Nom d'utilisateur
global.password = Mot de passe
global.submit = Soumettre

global_de.properties


#Global messages
global.username = Benutzername
global.password = Kennwort
global.submit = Einreichen
Please read this Struts 2 resource bundle example to understand how Struts 2 search the properties file automatically.

3. Action

Two action classes, the LocaleAction is basically do nothing, and the LoginAction will do a simple validation and display the error message from resource bundle via getText().

LocaleAction.java


package com.mkyong.common.action;

import com.opensymphony.xwork2.ActionSupport;

public class LocaleAction extends ActionSupport{

	//business logic
	public String execute() {
		return "SUCCESS";
	}
}

LoginAction.java


package com.mkyong.user.action;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport{

	private String username;
	private String password;
	 
	//...getter and setter methods

	//business logic
	public String execute() {
		return "SUCCESS";
	}

	//simple validation
	public void validate(){
		if("".equals(getUsername())){
			addFieldError("username", getText("username.required"));
		}
		if("".equals(getPassword())){
			addFieldError("password", getText("password.required"));
		}
	}
}

4. View page

A login page with a textbox, password and submit UI components.

To support Struts 2 localization, you HAVE TO declared the <%@ page contentType=”text/html;charset=UTF-8″ %> in your view page, else you will have problem to display the “UTF-8 data” correctly, especially the Chinese characters. Read this article about Struts 2 Chinese localization issue.

login.jsp


<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
</head>

<body>
<h1>Struts 2 localization example</h1>

<s:form action="validateUser" namespace="/user">

	<s:textfield key="global.username" name="username" />
	<s:password key="global.password" name="password"/>	
	<s:submit key="global.submit" name="submit" />
	
</s:form>

<s:url id="localeEN" namespace="/" action="locale" >
   <s:param name="request_locale" >en</s:param>
</s:url>
<s:url id="localezhCN" namespace="/" action="locale" >
   <s:param name="request_locale" >zh_CN</s:param>
</s:url>
<s:url id="localeDE" namespace="/" action="locale" >
   <s:param name="request_locale" >de</s:param>
</s:url>
<s:url id="localeFR" namespace="/" action="locale" >
   <s:param name="request_locale" >fr</s:param>
</s:url>

<s:a href="%{localeEN}" >English</s:a>
<s:a href="%{localezhCN}" >Chinese</s:a>
<s:a href="%{localeDE}" >German</s:a>
<s:a href="%{localeFR}" >France</s:a>
 
</body>
</html>
To change the default locale, you just need to declared a “request_locale” parameter, set your prefer language code and pass to an Action class. In Struts 2 the com.opensymphony.xwork2.interceptor.I18nInterceptor interceptor, which declared in the struts-default.xml, will hijack your Action class and handle the locale stuff accordingly.

5. Display the resource bundle message?

In Struts 2 , there are many ways to display the resource bundle message base on the selected language or locale. For examples,


<s:textfield key="global.username" name="username" />
<s:text name="global.username" />	
<s:property value="getText('global.username')" />
<s:text name="global.password" />
In Struts 1, there are one standard bean:message to display the resource bundle message, which is more prefer. But in Struts 2, there are so many equivalent ways to display the resource bundle message (even internal work is different), it’s quite confuse at the first glance. Basically, no matter what you choose, Struts 2 also will display the resource bundle message correctly.

6. struts.xml

Struts 2 configuration file, link it all together.


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>

	<constant name="struts.custom.i18n.resources" value="global" />
 	<constant name="struts.devMode" value="true" />
 	
	<package name="user" namespace="/user" extends="struts-default">
	   <action name="login">
		<result>pages/login.jsp</result>
	   </action>
	   <action name="validateUser" class="com.mkyong.user.action.LoginAction">
		<result name="SUCCESS">pages/welcome.jsp</result>
		<result name="input">pages/login.jsp</result>
	   </action>
	</package>
	
	<package name="default" namespace="/" extends="struts-default">
	   <action name="locale" class="com.mkyong.common.action.LocaleAction">
		<result name="SUCCESS">user/pages/login.jsp</result>
	   </action>
	</package>
	
</struts>

7. Demo

http://localhost:8080/Struts2Example/user/login.action
http://localhost:8080/Struts2Example/locale.action?request_locale=en

Struts2 localization english

http://localhost:8080/Struts2Example/locale.action?request_locale=zh_CN

Struts2 localization chinese

http://localhost:8080/Struts2Example/locale.action?request_locale=de

Struts2 localization German

http://localhost:8080/Struts2Example/locale.action?request_locale=fr

Struts2 localization France

Reference

  1. http://struts.apache.org/2.1.8/docs/localization.html
  2. http://www.mkyong.com/java/java-convert-chinese-character-to-unicode-with-native2ascii/
  3. http://www.mkyong.com/struts2/struts-2-resource-bundle-example/
  4. http://www.mkyong.com/struts/struts-internationalizing-or-localization-example/
author image

mkyong

Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities. Read all published posts by

Comments

avatar
48 Comment threads
6 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
47 Comment authors
Shravan kumar Yadavsreetama sarkarMatt DargaamitClarice Recent comment authors
newest oldest most voted
DineshT
Guest
DineshT

Needs a detailed explanation of the interceptors and value stack topic concepts in struts2 framework

Pablo
Guest
Pablo

This is driving me crazy.
The locale change when I press on any of the languages and come back to the login page, which in my case is a simple index.jsp. But If after that I decide to type the url for the index.jsp the locale comes back to the original language. Isn’t supposed that the interceptor will take care of the locale once you submit the request_local parameter? There is almost no docs about this. help please.!

rodolfo
Guest
rodolfo

great tutorial!! but i still got a question.

how can i internationalize the Browse button created by an tag?
by setting the key value it just set the label of the input but not the button automatically created by the

pars
Guest
pars

i tried your tutorial after i have experienced some i18n mysteries on my own. but with your tutorial i can see the same mysterious things: my default i18n properties are never showing up. even if i click on “http://localhost:8080/Struts2i18nDemo/locale.action?request_locale=en” i get only the results from http://localhost:8080/Struts2i18nDemo/locale.action?request_locale=de it seems that somehow request_locale=de is the default for me, but why? i cannot change it to request_locale=en, but why? by the way: i am using glassfish 3.0.1. i have also experienced that in my own example, where i used struts 2 together with tiles, the tiles localozation/i18n works just fine but the struts2… Read more »

David
Guest
David

In struts 1 there was a different approach that now seems to be impossible with version 2: you could extend org.apache.struts.util.MessageResources with your own implementation for resolving messages (against a database or wherever) and set it as an attribute of the servlet context named Globals.MESSAGES_KEY.

Then, Struts would use that implementation to resolve the messages associated to any requested key.

Until now I have not seen that it’s possible to do it with struts2.

Any ideas?

Patrick
Guest
Patrick

when using “s:select”, if the list of data returned by my java class contains strings that have unicode characters in them, “s:select” fails to generate the entire tag, it dies at the unicode character.

any ideas how to fix this?

for example, this tag:

now “userTypeList” returns as it’s first item the string “Actualizaci√≥n_GZ”

the resulting page source is:

<option value="Actualizaci

it ends/dies at the character "ó"

ideas?

trackback
struts2 i18n & ModelDriven - Java Forums

[…] & ModelDriven dear all i have a problem about struts2 i use following example : Struts 2 – i18n or localization example to implements i18n that's works OK but when i modify the example i use <s:text […]

Musthafa
Guest
Musthafa

an easy to follow great example.

Manish
Guest
Manish

I am stuck at the very begining, I have the action defined in struts.xml:

/login.jsp

which my Jsp page is calling :

da

but im getting this error on clicking on link on JSP page:
No result defined for action org.myapplication.action.LocaleAction and result success

trackback
Struts 2 Tutorials

[…] i18n or localization example A Struts 2 internationalizing or multi-language example to show the use of resource bundle to display the message from different languages. […]

Pravin Gupta
Guest
Pravin Gupta

A very good example. Thanks.

Kailash
Guest
Kailash

I downloaded your source code tried to execute, but am getting the below error,

type Status report

message There is no Action mapped for action name login.

description The requested resource (There is no Action mapped for action name login.) is not available.

WARNING: Could not find action or result
There is no Action mapped for action name login. – [unknown location]
at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:189)
at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:61)
at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:488)
at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:279)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Crazy IMG
Guest
Crazy IMG

It is a great example for dandling text display in i18n. I am wondering how to handle images with text of different languanges in them in i18n? How to switch them according to locale selections?

Thanks in advance!

abdul vahab
Guest
abdul vahab

what happpen when give link like http://localhost:8080/Struts2Example/locale.action?request_locale=zh (change zh_CN to zh)

kk
Guest
kk

kkk

kitokid
Guest
kitokid

here is the list of jar files to avoid hitting excpetions. I hope this will be a help for everyone.Please use suitable jar files because for my case, I use the latest struts2.

commons-fileupload-1.2.2
commons-io-2.0.1
commons-lang-2.4
commons-lang3-3.1
commons-logging-1.1.1
commons-logging-api-1.1
commons-validator-1.3.1
freemarker-2.3.19
javassist-3.11.0.GA
ognl-3.0.5
struts2-core-2.3.4
xwork-core-2.3.4

Daruwin
Guest
Daruwin

Hi, what ID do you use?
Thanks

Daruwin
Guest
Daruwin

IDE… Integrated Development Environment? Thanks

priya
Guest
priya

wen i selecting languages getting error dis way
You are seeing this page because development mode is enabled. Development mode, or devMode, enables extra debugging behaviors and reports to assist developers. To disable this mode, set:

struts.devMode=false

in your WEB-INF/classes/struts.properties file.

can u plzz help me

priya
Guest
priya

help me

Sergey
Guest
Sergey

What if I want to put the global.properties file inside some package in the classpath? How should I write struts.custom.i18n.resources property in this case?

peterwkc
Guest
peterwkc

How to implement localization for current rather than redirect to index.jsp like KWSP website?

Please help asap.

ravi
Guest
ravi

how to maintain chinese as it is in “global_zh_CN.properties” file like english and other…
but not like unicode(as above example).

thanks

ravi
Guest
ravi

how to maintain as it is “global_zh_CN.properties ” like english and other but not like unicode as above example

guillem
Guest
guillem

It is a great example for dandling text display in i18n. I am wondering how to handle images with text of different languanges in them in i18n? How to switch them according to locale selections?

shaik
Guest
shaik

Great job…..!!!

mahendar
Guest
mahendar

great tutorial!! but i still got a different Problem.

I am using the following tags. But i got Symbols instead of characters in my view page.

dentist washington dc
Guest
dentist washington dc

What’s up to every one, the contents present at this web site are actually remarkable for people knowledge, well, keep up the good work fellows.

Aaron Rodgers Jersey Womens Aaron Rodgers Jersey Authentic
Guest
Aaron Rodgers Jersey Womens Aaron Rodgers Jersey Authentic

Hi mates, nice piece of writing and good urging
commented here, I am really enjoying by these.

best trading strategies
Guest
best trading strategies

I appreciate your insight on this interesting topic. I am happy that I have found your blog because it will surely help in my
subsequent investing decisions. I will most definitely be back
again in the future. By the way, is there a subscription
for your site? I did not notice where to sign up on your blog.

Air Max Skyline
Guest
Air Max Skyline

Hi, after reading this awesome piece of writing i am also happy
to share my know-how here with friends.

Mujahid
Guest
Mujahid

hi, Thanks for the tutorial…. I’m a beginner so why no clue whether is silly one, any ways. When i tried the above it is working absolutely fine for me. but this locale will be set only for that particular page, (say for login page in mine project). once user login again it will be set global.properties. I’m just trying to know how can i set it to app level than just for a page or request level.

Thanks in Advance.