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

2. Properties file
Make sure the properties file are named as country specified code.
global.properties
#Global messages
global.username = Username
global.password = Password
global.submit = Submitglobal_zh_CN.properties
#Global messages
global.username = \u7528\u6237\u540d
global.password = \u5bc6\u7801
global.submit=\u63d0\u4ea4global_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 = Einreichen3. 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.
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>
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" />
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

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

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

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

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

After checking out a few of the blog articles
on your site, I really appreciate your technique of writing
a blog. I saved as a favorite it to my bookmark webpage list and will be checking back soon.
Please visit my web site too and tell me what you think.
Hey there just wanted to give you a quick heads up.
The text in your post seem to be running off the screen
in Chrome. I’m not sure if this is a formatting issue or something to do with internet browser compatibility but I thought I’d post to let
you know. The design look great though! Hope you get the issue fixed soon.
Kudos
i get changed language on buttons but not on labels.on labels it is giving like this ???.??
plz help………..
what to do run this example
i am new in this field
error on my page using this example
type Status report
message /Struts2Example/user/pages/login.jsp
description The requested resource is not available.
what to do ?
what about error messages..??
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.
Hi, after reading this awesome piece of writing i am also happy
to share my know-how here with friends.
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.
Hi mates, nice piece of writing and good urging
commented here, I am really enjoying by these.
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.
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.
Great job…..!!!
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?
how to maintain as it is “global_zh_CN.properties ” like english and other but not like unicode as above example
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
How to implement localization for current rather than redirect to index.jsp like KWSP website?
Please help asap.
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?
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
help me
Hi, what ID do you use?
Thanks
IDE… Integrated Development Environment? Thanks
Eclipse ~
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
kkk
what happpen when give link like http://localhost:8080/Struts2Example/locale.action?request_locale=zh (change zh_CN to zh)
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!
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)
A very good example. Thanks.
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
an easy to follow great example.
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?
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?
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 localozation/i18n does not (same result as described above).
any idea?
That’s weird, mind to zip it and send me for debugging? (exclude the dependency)
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
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.!
“type the url for the index.jsp” will caused a new session to your application, and the locale will revert back to the default value.
To keep track the locale history, you can store a cookies in the client side.
Needs a detailed explanation of the interceptors and value stack topic concepts in struts2 framework
Here’s got few interceptor examples, http://www.mkyong.com/tutorials/struts-2-tutorials/
Regarding the value stack, just treat it as a storage for your application. May create value stack article in future.