Java GWT:在服务器代码中访问i18n消息
我有一个扩展Java GWT:在服务器代码中访问i18n消息,java,gwt,Java,Gwt,我有一个扩展com.google.gwt.i18n.client.Messages类的接口,用于在gwt应用程序中检索i18n消息。看起来是这样的: public interface MyMessages extends com.google.gwt.i18n.client.Messages { @DefaultMessage("Hello world") @Key("message1") String message1(); @DefaultMessage("Hello ag
com.google.gwt.i18n.client.Messages
类的接口,用于在gwt应用程序中检索i18n消息。看起来是这样的:
public interface MyMessages extends com.google.gwt.i18n.client.Messages {
@DefaultMessage("Hello world")
@Key("message1")
String message1();
@DefaultMessage("Hello again")
@Key("message2")
String message2();
//...
}
通常,我使用GWT.create()
创建它的实例,如下所示:
private MyMessages messages = GWT.create(MyMessages.class);
但是,这不适用于服务器端代码,只适用于客户端代码(它会抛出一个错误,指出GWT.create()仅在客户端代码中可用)
a的答案指向一个单独的库,您可以下载它,它将允许您访问服务器上的i18n消息,但我不想下载任何额外的库(这似乎是一个简单的问题,必须有一个简单的解决方案)
总而言之:我如何在服务器端代码中访问我的i18n消息?谢谢。在服务器端,您可以使用标准的Java本地化工具,如。 寻找如何使用它的教程
// Create a ResourceBundle out of your property files
ResourceBundle labels =
ResourceBundle.getBundle("LabelsBundle", currentLocale);
// Get localized value
String value = labels.getString(key);
特定于GWT的从属性文件创建接口并通过延迟绑定提供实现的方法不能在服务器端Java上使用
如果您无所畏惧并且愿意花时间,那么可以实现代码生成步骤来读取属性文件并为消息接口生成实现类。这正是谷歌GWT编译器在幕后所做的。我同意迈克尔的观点。。我遇到了这样一个问题:试图“本地化”服务器上生成的消息。。。。但是我决定只在服务器上抛出一个异常(因为这是一个错误消息,应该只在异常情况下发生),其中包含消息代码,然后客户端代码可以查找该代码并向用户显示正确的本地化消息。有一个用于GWT国际化的强大库。它允许您在clent和服务器之间“共享”.properties文件。但是,作者似乎放弃了该项目,您必须手动重新编译它,以便与GWT versio>=2.1.0一起使用。GWT.create()只能在客户端代码中使用 好的做法是提供自己的I18N提供程序类/接口,然后可以从中扩展到服务器端I18N工厂和客户端I18N工厂读取相同的资源包 之后,您可以简单地在整个系统中使用它,统一您的代码。
希望这能有所帮助。根据vanje的回答,并考虑到属性文件使用的编码(这可能会很麻烦,因为ResourceBundle默认使用“ISO-8859-1”),下面是我提出的解决方案:
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;
}
}
}
使用此功能的方法与常规ResourceBundle使用非常相似:
private MyResourceBundle labels = new MyResourceBundle("es", "UTF-8");
String label = labels.getString(key)
或者,您可以使用默认情况下使用UTF-8的备用构造函数:
private MyResourceBundle labels = new MyResourceBundle("es");
我在我的GWT项目中使用Maven,其中一个好处是它查看您的Messages.properties文件并自动为您生成消息接口。使用ResourceBundle是可行的,但我仍然讨厌为服务器端代码做一些单独的事情。也许Google说,“设计良好的应用程序不需要访问服务器端的i18n消息。"事实上,现在我想起来了,我认为只有客户端才能访问消息是有意义的。服务器总是具有相同的区域设置,因此无论客户端处于哪个区域设置,它都将始终返回相同的消息。例如,如果服务器位于加利福尼亚州,它将始终检索英语消息使用服务器的默认区域设置使用英语。当编译为Javascript时,GWT可能会发挥一些魔力来确定web用户的区域设置并使用适当的.properties文件。@Michael这就是您拒绝的库的原因(我理解您的动机!)使客户机在服务器端设置语言环境…使用Renato的消息代码系统是一种方法,尽管它很难自定义消息(“无法打开文件'foo'”和类似内容)是的,我认为这是一个很好的解决方案。这就是我要做的,但我很懒,决定只访问服务器上的Messages.properties文件,因为我的应用程序将永远只使用一种语言。:)好主意。有时我们必须传递额外的信息,但它可以作为特定异常的参数包含在内。感谢您的回复。你是说我可以创建一个类,用于在客户端和服务器上检索消息?那太好了。现在,我正在为每个人使用单独的类。很抱歉反应太晚。是的,这就是重点,单独的类已经足够好了,问题是您可以创建一个facade在运行时访问两个不同的类,这将节省您大量的时间,并为您提供更整洁的代码。