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/
Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

  • Pingback: stream movies()

  • Pingback: Blue Coaster33()

  • Pingback: Google()

  • http://nitinsurana.com Nitin

    Once the language is changed, will this work for the complete application ? and other pages/actions ?

    Is it automatically setted/stored in the session or something ?

    Regards
    Nitin

  • http://www.level5.com.pl studio reklamy lubin

    Howdy great blog! Does running a blog such as this require a great deal of work?
    I’ve very little understanding of coding but I had been hoping to start my own blog in the near future. Anyway, if you have any ideas or techniques for new blog owners please share. I know this is off subject but I simply had to ask. Kudos!

  • krishna

    easy to understand

  • Saleem

    Dear Mkyong,

    Thanks for your tutorial, sorry to say but its little urgent for me, will you please give a little abstract for me like, I don’t have Uni-Code text, I have only plain Arabic text, I’ve using same struts, but in browser all characters are showing in strange values. I can’t use Uni-Code in any ways because my higher authorities are not listing to my words.

  • http://www.javaaster.com Tarun

    Grate tutorials thanks …….

  • Struts2_user

    Hello,
    Thank to you for the quality of your tutorials, it?s really helpful.

    I want ask the same question as Visitor
    Do you have any examples of radio buttons or dropdown lists …..

    Thanks

  • Visitor

    Do you have any examples of radio buttons or dropdown lists that populated from resources properties files to support bilingual application?

  • http://treeglider8.wordpress.com/2013/04/26/good-advice-to-remember-when-you-go-camping/ extra resources

    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.

  • http://cooperativehabitation.coop/airmax.html Princess

    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

  • http://[email protected] Riaz

    i get changed language on buttons but not on labels.on labels it is giving like this ???.??
    plz help………..

  • PAnky

    what to do run this example
    i am new in this field

  • PAnky

    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 ?

  • amit

    what about error messages..??

  • 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.

  • http://www.frairmaxstore.com Air Max Skyline

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

  • http://www.worldstockscan.com 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.

  • http://www.packerssportstore.com 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.

  • http://dentistchelmsford.com/about/ 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.

  • 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.

  • shaik

    Great job…..!!!

  • http://www.nbwebas.com 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?

  • ravi

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

  • 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

  • peterwkc

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

    Please help asap.

  • 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?

  • 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

      help me

  • Daruwin

    Hi, what ID do you use?
    Thanks

    • Daruwin

      IDE… Integrated Development Environment? Thanks

    • http://www.mkyong.com mkyong

      Eclipse ~

  • 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

  • kk

    kkk

  • http://www.javamagics.blogspot.in/ abdul vahab

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

  • 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!

  • 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)

  • Pravin Gupta

    A very good example. Thanks.

  • Pingback: Struts 2 Tutorials()

  • 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

  • http://seermind.blogspot.com Musthafa

    an easy to follow great example.

  • Pingback: struts2 i18n & ModelDriven - Java Forums()

  • 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?

  • 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?

  • 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 localozation/i18n does not (same result as described above).

    any idea?

    • http://www.mkyong.com mkyong

      That’s weird, mind to zip it and send me for debugging? (exclude the dependency)

  • 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

  • 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.!

    • http://www.mkyong.com mkyong

      “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.

  • DineshT

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