Client side Internationalization in struts application with javascript
Struts gives a straightforward way to internationalize your application. Using properties files, you can display different messages to users with different locales. For details on how to internationalize your application, view the struts 1.x site. However, this kind of internationalization works best only for non-dynamic sites. For even slightly dynamic sites, where you have a client side javascipt validation, you would run into a problem.
The problem with javascipt is that you typically cannot pick up messages from a resource bundle (from the server) depending on user’s locale. I would discuss here how to get the properties file to client side (javascript) in a usable form. The idea is, we convert the properties file as a JSON which is readily available for use in javascript.
Suppose we have a file named MessageResources.properties for the default locale (EN). And another file named MessageResources_de.properties for the german locale. Struts i18n will take care of the internationalization in the JSP side, but for javascript, we need to make the properties available on the outputted HTML as a javascript variable.
Here is a sample code which accomplishes the same in struts action class:
import java.util.Enumeration;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
public class ActionInitializer extends Action{
public void execute(HttpServletRequest request, HttpServletResponse response){
Locale locale= request.getLocale();
ResourceBundle resourceBundle = (PropertyResourceBundle) ResourceBundle.getBundle("MessageResources",locale);
StringBuilder resourceJson = new StringBuilder();
resourceJson.append("{");
Enumeration<String>keys=resourceBundle.getKeys();
while(keys.hasMoreElements()) {
resourceJson.append("\"");
String key=keys.nextElement();
String value=resourceBundle.getString(key);
resourceJson.append(key);
resourceJson.append("\":\"");
resourceJson.append(value);
resourceJson.append("\",\n");
}
resourceJson.append("\"complete\":\"completed json text\"");
resourceJson.append("}");
request.setAttribute("resourceJson", resourceJson);
//
//Your business logic goes here
//
return mapping.findForward("success");
}
}
Couple of things to note, don’t forget to escape the double quotes, and don’t finish your JSON with a comma (which is why I have added a dummy element – ‘complete’) otherwise the generated JSON will throw a javascript error in IE6.
The above code will generate a JSON object which is stored as an attribute, accessible in the JSP. This sample code illustrates how to use this JSON to store the properties
<script type="text/javascript">
var resourceJson=eval(${requestScope.resourceJson});
alert(resourceJson["complete"]);
</script>
Note that in the first line, var resourceJson=eval(${requestScope.resourceJson});, the el is evaluated at the server side, so the outputted HTML will look something like this:
<script type="text/javascript">
var resourceJson=eval({
"text.hello":"Willkommen",
"text.contact":"Kontact",
"complete":"complete"});
alert(resourceJson["complete"]);
</script>
The ‘alert’ is only for demonstrating how you can access your locale specific message from the JSON. Happy i18n