English 中文(简体)
Localized exceptions (within a Struts2 app)
原标题:

I am developing a Struts 2 application with support for multiple languages. If one of the domain objects needs to throw an exception, how can it do so in such a way that the error message is no language-specific? And how can that exception later be displayed based on the current locale?

I was originally looking for a way to localize the error message at the point where it is thrown, but realized that this is not the best way because (a) it introduces an unnecessary dependency between the business model and the web framework; and (b) language should be determined by the current locale when the exception is displayed, not when it is thrown.

So I m wondering how other people have approached this problem. (And I don t think this is really specific to Struts 2, but relevant to any multi-lingual application).

问题回答

After noticing that Throwable has a method called getLocalizedMessage(), I decided to use this in my solution.

My class BusinessException extends Exception, and its constructor takes a key representing the error:

public BusinessException(String key, Object[] arguments) {
    this.key = key;
    this.arguments = arguments;
    this.locale = Locale.getDefault();
}

As you can see, the locale defaults to the JVM s default locale. However, in a web application the current request s locale should be used instead. So, BusinessException provides a setLocale() method which should be called before getLocalizedMessage(). Hence, in a Struts2 action the idiom is something like:

try {
    // call business objects
}
catch(BusinessException be) {
    be.setLocale(ActionContext.getContext().getLocale());
    addActionError(be.getLocalizedMessage());
    return ERROR;
}

For the record, the localized messages come from the family of resource bundles for the exception class: BusinessException.properties, etc. The Struts2 application also has an application-wide resource bundle, but I decided not to use that to avoid dependencies by the business objects on the web framework.

Just display the error message in the language you want at the level where you catch and handle the exception, not where you throw it. If you need some extra information such as a username or an identifier, just create a property in your BusinessException class, so that you can use them in the displayed message.

try {
   doSomething();

} catch (BusinessException e) {
   LOG.error("Create your error message in English, it s good for logging", e);

   int id = e.getId();
   // internationalize here
}

Why would you throw exceptions with a locale specific message? I would keep them English all the time. You can make your error page locale specific however. Show a locale specific message that something has failed and what the user is supposed to do and that the user can find the details here below (insert plain English error details here). For basic validation messages ("This is required", "Please enter valid email", etcetera) of course use locale specific messages.

I guess the error page need to use the localized strings to display errors as per the locale. Define your standard messages in respective locale specific files and struts 2 should render them as per the working locale. (see how s:text works).

To define a locale specific file and place where to put them in application see Struts 2 Localization





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签