Localization (i18n) in Struts2
December 14, 2011 by Sandeep Bhardwaj | Tags: Struts2
A Struts 2 internationalizing(i18n), localization(i10n) example to show the use of resource bundle to display the message from different languages.
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.
In Struts 2 web application you may associate a message resource property file with each Struts 2 Action class by creating a properties file with the same name as the Action class and having the .properties extension. This properties file must go in the same package as the Action class.
About the Application
- Application has links for 2 language ,On clicking the link, change the locale base on the selected language option.
- English
- German
- Also cover the use of global.properties file.
Package Structure
Jar needed
Resource Bundle search order
Resource bundle is searched in the following order
- ActionClass.properties
- Interface.properties
- BaseClass.properties
- ModelDriven’s model
- package.properties
- Search up the i18n message key hierarchy itself
- Global resource properties
common used search orders will be :
- ActionClass.properties,
- package.properties and
- Global resource properties.
If a com.mycomp.action.LoginAction want to get a message via resource bundle, it will search
- com.mycomp.action.LoginAction.properties (found, exit, else next)
- com.mycomp.action.package.properties (found,exit, else next)
- com.mycomp.package.properties (found exit, else next)
….keep find package.properties in every parent directory all the way to the root directory - Find the global resource properties if you configure it in your application
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Struts2Practice</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
struts.xml
<?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.devMode" value="true" />
<constant name="struts.custom.i18n.resources" value="global" />
<package name="default" namespace="/" extends="struts-default">
<action name="helloworld" class="com.mycomp.action.HelloWorld">
<result name="success">/helloworld.jsp</result>
</action>
<action name="login" class="com.mycomp.action.LoginAction">
<result>/login.jsp</result>
</action>
<action name="register" class="com.mycomp.action.UserRegisterAction">
<result>/userRegistration.jsp</result>
</action>
</package>
</struts>
helloworld.jsp
In the commands section of the page has 2 links:-
- User Registration
- Login
and Languages section has 2 links for language:-
- English
- German
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h2>Welcome ;-)<s:property value="message"/></h2>
<h2>Commands:</h2>
<ul>
<li><a href="<s:url action="register"/>">New User</a></li>
<li><a href="<s:url action="login"/>">Login</a></li>
</ul>
<h2>Languages</h2>
<ul>
<li>
<s:url id="url" action="login">
<s:param name="request_locale">en</s:param>
</s:url>
<s:a href="%{url}">English</s:a>
</li>
<li>
<s:url id="url" action="login">
<s:param name="request_locale">de</s:param>
</s:url>
<s:a href="%{url}">German</s:a>
</li>
</ul>
</body>
</html>
Struts2 provide the
helloworld.jsp demonstrate the 2 different ways to use the tag :-
<a href=”
When the link is rendered, the tag will automatically append the appropriate extension.
The tag will also URL-encode the link with the Java session ID, if needed, so that the Java session can be retained across requests.
<s:url id="url" action="Welcome">
<s:param name="request_locale">en</s:param> </s:url>
<s:a href="%{url}">English</s:a>
The param tag will add the parameter “?request_locale=en” to the Welcome Action URL, and store it under the name “url”. The tag then injects the “url” reference into the hyperlink.
HelloWorld.java
package com.mycomp.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorld extends ActionSupport{
private static final long serialVersionUID = 1L;
public static final String MESSAGE = "In the Struts2 World !!";
private String message;
public String execute()
{
setMessage(MESSAGE);
return "success";
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login</title>
</head>
<body>
<s:form action="login">
<s:textfield key="login.username" />
<s:password key="login.password" />
<s:submit key="login.submit" />
</s:form>
</body>
</html>
In Struts 2 “key” attribute can be used in the textfield tag to instruct the framework what value to use for the textfield’s name and label attributes.
Instead of providing those attributes and their values directly, you can just use the key attribute.
→ textfield tag
Instead of specifying the name and label attributes you can just use the key attribute.
→ textfield tag with key attribute
To enable the key attribute to find the properties file, the display of the view page must be the result of executing a Struts 2 Action class.
So, let see the LoginAction.java.
package com.mycomp.action;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
private String username;
private String password;
public String execute()
{
return "success";
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Make sure the properties file are named as country specified code.
LoginAction.properties
# LoginAction : english language
login.username = Username
login.password = Password
login.submit = Submit
LoginAction_de.properties
# Login action : German language
login.username = Benutzername
login.password = Kennwort
login.submit = Einreichen
userRegistration.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Register New User</title>
</head>
<body>
<s:form>
<s:textfield key="global.username" name="username" />
<s:password key="global.password" name="password"/>
<s:password key="global.conpassword" name="conpassword"/>
<s:submit key="global.submit" name="submit" />
</s:form>
</body>
</html>
UserRegistrationAction.java
package com.mycomp.action;
import com.opensymphony.xwork2.ActionSupport;
public class UserRegisterAction extends ActionSupport {
public String execute()
{
return "success";
}
}
Global.properties
#Global messages
global.username = Username
global.password = Password
global.conpassword = Confirm Password
global.submit = Submit
The keys and values defined in that property file will be available to all the view pages that are rendered after executing an Action class.</div>
To inform the Struts 2 framework about the global.properties file add the follow node to struts.xml after the constant name=”struts.devmode” node.
<constant name="struts.custom.i18n.resources" value="global" />
Now run the application:
http://localhost:8081/Struts2Practice/helloworld.action