tags:

views:

324

answers:

2

In Java Server Faces, we normally get the locale of the current request with the UIViewRoot.getLocale() method, which would normally return the locale set in the browser. In a layered application, how can I read the same locale in other layers, where there's no access to the JSF objects? It seems that Locale.getDefault() is not suitable, because it returns a JVM-wide default locale. I need the context locale, set only by the current request from the browser. I assume it needs to have some kind of thread-affinity, like with .NET's Thread.CurrentCulture property.

+1  A: 

You can pass it as an argument to methods that need it. This is, I think, the best approach.

public void businessMethod(String someArg, int otherArg, Locale locale) {
   ..
}

It however requires modifying your method signatures. You can implement something like in .NET via:

public final class LocaleProvider {
    private static ThreadLoca<Locale> currentLocale;
    //static setters and getters for the threadLocal
}

But this is essentially what FacesContext.get....getLocale() is doing. So except for getting rid of the dependencies on JSF in your service layer, you are not doing much more.

That said, current Locale should rarely be needed in the business operations. Two examples I can think of:

  • sending emails (the appropriate template should be chosen)
  • generating documents (like pdf) in the appropriate language

So, think twice before you include a locale dependency in your business-logic.

Bozho
Interesting roll-your-own solution. But I was looking more for an official, in-the-framework, way of doing this, like in .NET. If it doesn't exist, I'll probably go with your idea.
Jordão
+1  A: 

Not really the answer you probably expect, but in a layered design the answer should be: you don't.

Only the presentation layer is supposed to do data formatting according to the locale.

The business layer and the data layer should hold and manipulate data in locale-independent fashion.

ewernli
in rare cases it needs the locale (see my answer)
Bozho
I would argue that these cases that have to do with customer communication are better supported if you introduce a customer entity that has all the preference for the customer, such as default language, email address, etc. Then you pass the customer entity along. Most of the time, I don't want the communication in french while my browser is in english :) But I see your point though.
ewernli
The locale can also be used for, e.g., getting the product names in the user's language from the data access layer. Isn't this a valid point for accessing the locale of the user from lower layers?
Jordão
I agree that it's maybe not that black and white. How to deal with end-to-end internationalization of web application is an interesting question on its own.
ewernli