Wednesday, 25 April 2007

i18n in a java web app

There are at least a few strategies for supporting different languages (i18n) in a web app. These strategies are for non-constant data the the user controls which could change from request to request. For text that doesn't really change, it's best to use whatever i18n strategy that the MVC you are using recommends (ResourceBundles). I'm going to outline a few with the pro's and con's of each.

1) Walk the model
When you are passing the model to the view, you "walk" all of the objects, telling them what language they are supposed to display. The jsp is simple because you have just one "write" tag that is language agnostic. The bad part is that for every request you have to make sure you walk everything that's in every scope and make sure the model knows what language the request is. Not easy, and very error prone.

2) View knows what what it speaks
The objects have methods for every language it supports. This means that the jsp's know what language the request is, and for every language that it supports there is a if / else clause to print out the correct text. This isn't so bad if you are supporting 2 languages. It's not something that you could use if you were supporting many languages though. It leads to messy jsp's and having to test the view for every language to ensure that it is rendering correctly.

3) Threading? Keep it local.
Using a static member is out since that would be shared across the jvm, not something you want for a multi threaded app. However, there is something that allows you to use static-like access while still being thread safe: ThreadLocal. This means that you can leave your view clean, and you don't have the complicated task of of walking the model. Through a filter, you can set what the language is and then you are just coupling the model to a "language helper" that has a ThreadLocal member. One downside is that each model object will have logic for every language to support, for every field. Not too bad, since you have to put it somewhere, and with this method you only do it in one place.

I've always used #2, but have never really been happy with it. I have not used #3 yet, but I have seen it used. When I saw it I had one of those "why didn't I think of that!" type of moments. I'm looking forward to making my code cleaner. ;-)

3 comments:

  1. The title isn't all that clear -- I couldn't tell you were talking about I18N at first. I thought maybe it was programming languages. ;)
    As for the solution, how about a string table or file with constants in the view? This is how Eclipse does it.

    ReplyDelete
  2. I changed the title... Hope that's clearer. ;-)
    The solutions that I outlined are for text that the user controls that is stored in the db and the user controls. I changed the first paragraph of the post to try and clarify that.

    ReplyDelete
  3. I've always found that internationalization never had an elegant solution. Or at least none that I've ever seen. I've worked on a variety of projects that were multilingual, and while they all had their ways of doing it, none of the solutions really seemed optimal.

    ReplyDelete