java - 如何避免 Java ResourceBundle 字符串中的重复?

标签 java substitution resourcebundle

我们有很多包含相同子字符串的字符串,从关于检查日志或如何联系支持的句子到包含公司或产品名称的类似品牌的字符串。重复给我们自己造成了一些问题(主要是拼写错误或复制/粘贴错误),但它也导致了问题,因为它增加了我们翻译人员必须翻译的文本量。

我想出的解决方案是这样的:

public class ExpandingResourceBundleControl extends ResourceBundle.Control {
  public static final ResourceBundle.Control EXPANDING =
    new ExpandingResourceBundleControl();

  private ExpandingResourceBundleControl() { }

  @Override
  public ResourceBundle newBundle(String baseName, Locale locale, String format,
                                  ClassLoader loader, boolean reload)
    throws IllegalAccessException, InstantiationException, IOException {

      ResourceBundle inner = super.newBundle(baseName, locale, format, loader, reload);
      return inner == null ? null : new ExpandingResourceBundle(inner, loader);
  }
}

ExpandingResourceBundle 委托(delegate)给真正的资源包,但执行 {{this.kind.of.thing}} 的转换以查找资源中的键。

每次你想得到其中之一,你必须去:

ResourceBundle.getBundle("com/acme/app/Bundle", EXPANDING);

这在一段时间内效果很好。

最终发生的是一些新代码(在我们的例子中是从 Matisse 吐出的自动生成的代码)在没有指定自定义控件的情况下查找相同的资源包。如果您编写一个简单的单元测试来调用它,然后不调用它,这似乎是不可重现的,但是当应用程序真正运行时会发生这种情况。 ResourceBundle 中的缓存以某种方式弹出了好的值并用损坏的值替换它。我还没有弄清楚为什么 Sun 的 jar 文件是在没有调试信息的情况下编译的,所以调试它是一件苦差事。

我的问题:

  1. 是否有某种方法可以全局设置我可能不知道的默认 ResourceBundle.Control?这将相当优雅地解决所有问题。

  2. 有没有其他方法可以优雅地处理这种事情,也许根本不会篡改 ResourceBundle 类?

最佳答案

我认为这是 ResourceBundle 设计功能的一个根本缺陷:引用其他键的键会自动违反 DRY(不要重复自己)原则。我解决这个问题的方法与您的方法类似:创建一个 ReflectiveResourceBundle 类,允许您使用 EL 表示法在消息中指定资源键。

错误的方式:

my.name.first=Bob
my.name.last=Smith
my.name.full=Bob Smith

正确的方法:

my.name.first=Bob
my.name.last=Smith
my.name.full=${my.name.first} ${my.name.last}

我已经 uploaded the code to GitHub这样您或其他任何人都可以下载它。此外,我还为使用 Stripes 框架 ( http://www.stripesframework.org/ ) 的任何人添加了一些示例代码,以帮助您快速启动和运行。

使它与标准 JSTL fmt 标签库一起工作的诀窍是设置一个拦截器,用我们自己的资源替换 HttpServletRequest 的资源。代码看起来像这样:

ResourceBundle bundle = MyStaticResourceHoldingTheBundle.getBundle();
Config.set(request, Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle, locale));

查看上面链接中的 stripes.interceptor 包以获取更多详细信息。

关于java - 如何避免 Java ResourceBundle 字符串中的重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2605379/

相关文章:

perl - 变量替换/扩展 - Perl 中的安全方式

regex - Perl QR//和替代

google-chrome - Chrome 字符替换

java - 如何从类路径中获取 ResourceBundle 文件?

java - 放置在资源包中时,撇号无法正确翻译

Java正则表达式预定义字符类?

java - 如何使用 JBOSS 配置摆脱谷歌浏览器中过时的密码套件问题

java - 如何在 java/javacv 中的图像上绘制检测到的关键点?

java - 在 spring 和 springboot 中从 src 代码外部化错误消息(资源包)的最佳方法是什么?

java - 呈现模板gsp时通过model属性检索传递的数据时缺少MissingMethodException