简体   繁体   中英

GWT: Accessing i18n messages in server code

I have an interface that extends the com.google.gwt.i18n.client.Messages class, which I use for retrieving i18n messages in my GWT application. It looks like this:

public interface MyMessages extends com.google.gwt.i18n.client.Messages {
  @DefaultMessage("Hello world")
  @Key("message1")
  String message1();

  @DefaultMessage("Hello again")
  @Key("message2")
  String message2();

  //...
}

Normally, I create an instance of it using GWT.create() like so:

private MyMessages messages = GWT.create(MyMessages.class);

However, this does not work with server-side code, only client-side code (it throws an error saying that GWT.create() is only usable in client-side code).

The answer to a similar question points to a separate library that you can download which will let you access the i18n messages on the server, but I don't want to download any extra libraries (this seems like a simple problem, there must be a simple solution).

In summary: How can I access my i18n messages in server-side code? Thanks.

On the server side you can use the standard Java localization tools like ResourceBundle . Look here for a tutorial how to use it.

// Create a ResourceBundle out of your property files
ResourceBundle labels =
  ResourceBundle.getBundle("LabelsBundle", currentLocale);

// Get localized value
String value = labels.getString(key);

The GWT specific way of creating an interface out of your property files and providing implementations via deferred binding can not be used on sever side Java.

If you are fearless and willing to spend the time, you can implement a code generation step to read your property files and generate implementation classes for your message interface. That's exactly what the Google GWT compiler does behind the scene.

我同意Michael ..我遇到了尝试“本地化”服务器上生成的消息的问题....但是我决定改为在服务器上抛出Exception(因为这是一条错误消息,应该只在异常情况下发生),其中包含消息代码,然后客户端代码可以查找并向用户显示正确的本地化消息。

There's a great library for GWT internationalization gwt-dmesg . It allows you to 'share' .properties files between clent and server. However, project looks to be abandoned by author and you must recompile it manually for use with GWT versio >= 2.1.0.

GWT.create() can only be used in client-side code.

The good thing to do is that you provide your own I18NProvider class/interface, from which then you can extend to server side I18N factory and client side I18N factory read the same resource bundle.

After that you can simply use it all over your system, unify your code. Hope that helps.

Following vanje's answer, and considering the encoding used for the properties files (which can be troublesome as ResourceBundle uses by default "ISO-8859-1", here is the solution I came up with:

import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.ResourceBundle;

public class MyResourceBundle {

    // feature variables
    private ResourceBundle bundle;
    private String fileEncoding;

    public MyResourceBundle(Locale locale, String fileEncoding){
        this.bundle = ResourceBundle.getBundle("com.app.Bundle", locale);
        this.fileEncoding = fileEncoding;
    }

    public MyResourceBundle(Locale locale){
        this(locale, "UTF-8");
    }

    public String getString(String key){
        String value = bundle.getString(key); 
        try {
            return new String(value.getBytes("ISO-8859-1"), fileEncoding);
        } catch (UnsupportedEncodingException e) {
            return value;
        }
    }
}

The way to use this would be very similar than the regular ResourceBundle usage:

private MyResourceBundle labels = new MyResourceBundle("es", "UTF-8");
String label = labels.getString(key)

Or you can use the alternate constructor which uses UTF-8 by default:

private MyResourceBundle labels = new MyResourceBundle("es");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM