Thursday, March 12, 2009

I18N your Java Web Application

I went through the exercise of internationalizing (I18N) my home project. It is still work in progress but I added support for German in most places. Unfortunately, I got a bit bitten by the fact that by default properties files in Java have to be encoded in ISO-8859-1. Up to today, all web applications I helped developing, were created for an English speaking target audience, and therefore, even though they often used properties files, they never went beyond the standard character set.

Interestingly, though, if you like using typographically correct characters like the ellipsis or quotation marks, you would run into the same issue. For that reason alone I think everything (Your JSP files, server, database, source code etc. should all be able to handle UTF-8)

Nevertheless, the limitation that properties files by default are not cannot be in UTF-8 is quite annoying, as it would require you to escape special non-ISO-8859-1 characters or use a conversion tools such as native2ascii. This blog post summarizes the general issue nicely.

For my project I am using Struts 2.1. By default it does not allow for UTF-8 based message resources. Since Java 6 introduced support for creating a custom loader when accessing resource bundles, I was looking into ways of maybe extending Struts 2. Well, it looks like Struts 2 does neither allow a custom ResourceBundle Control nor for easy patching of Struts itself. See also: https://issues.apache.org/struts/browse/WW-2774

Nevertheless, even though Struts 2.1 improved substantially compared to Struts 2.0.x, I am still debating whether long-term Spring MVC (Especially Spring MVC 3.0) might represent a better choice—With Spring 2.5+ both web frameworks are certainly getting very similar. The nice thing about Spring (Core) is, that it provides the ReloadableResourceBundleMessageSource which provides exactly what was looking for:

<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"/>
<property name="defaultEncoding" value="utf-8"/>
</bean>
Unfortunately, as mentioned above, it looks like there is not an easy pluggable way of convincing Struts 2's textprovider to use Spring's messageSource implementation. As I am already using Spring MVC for some of my actions, I decided to use Spring's message tag within my JSPs, I am not crazy about it, as I now mix different web-frameworks but it seems to work like a charm right now.

Two last questions to answer are:

What is the best way to edit resource bundles using eclipse?
How do ou structure your resource bundles without loosing track of things?

After searching the web for a while, I finally settled for Eclipse Resource Bundle Editor. It works quite nicely, I just wish something useful like this would be built into Eclipse by default.

As for structuring the property files, I settled pretty much on a jsp-by-jsp structure. E.g. if I have a file edit-settings.jsp and I want to customize the page title, then I create a resource bundle entry jsp.edit-settings.title=My settings

Similarily I deal with class files:

class.AddUserAcion.success = The user has been successfully registered.

Just as additional information: I wonder, whether it might be a cool thing, to be able to structure properties files similar to Rails 2.2+. There is an interesting RailsCast available about how to do I18N in Ruby On Rails.





No comments: