【问题标题】:Spring MVC: static ResourceBundleSpring MVC:静态资源包
【发布时间】:2013-06-27 15:18:56
【问题描述】:

我有很多控制器,它们扩展了一个基本控制器,它有一个带有 ResourceBundle 生成的静态构造函数:

static {
   resources = ResourceBundle.getBundle("com.resource.Resources");
}

我需要它,因为应用程序的逻辑基于语言环境,而不仅仅是视图。

此外,我还有一个CookieLocaleResolver,它可以从 cookie 中解析当前的语言环境。

问题是基本控制器的静态构造函数代码在 CookieLocaleResolver 的 resolveLocale 方法之前执行,所以我总是在 ResourceBundle 收到系统的默认语言环境,而不是当前语言环境。

我该如何解决?谢谢

【问题讨论】:

    标签: spring spring-mvc internationalization


    【解决方案1】:

    这是因为static 块是在类初始化时执行的。您需要在调用控制器时加载ResourceBundle。我建议您在这里将控制器定义为 prototype 并使用 InitializingBean 加载 ResourceBundle。

    public class MyController implements InitializingBean {
        private ResourceBundle resources;
    
        public void afterPropertiesSet() {
             resources = ResourceBundle.getBundle("com.resource.Resources");
        }
    }
    

    更好的方法是使用 ResourceBundleMessageSource 而不是直接使用 ResourceBundle。如果可以,那会容易得多,因为您不必直接管理 ResourceBundle。

    希望对你有帮助。

    [编辑]

    Spring MessageSource 提供了通过参数解析消息的方法。如果您在应用程序中定义MessageSource,您还可以在视图(例如JSP 页面)中访问相同的消息。最后,从设计来看,如果控制器没有对资源包的直接引用,这样会更好,这样您的标签/消息就可以在一个地方进行管理(在您声明 MessageSource 时在 Spring 配置中)。

    【讨论】:

    • 感谢您的回复,很有用。你能解释一下为什么使用ResourceBundleMessageSource 更好吗?据我了解,它的缓存比 ResourceBundle 的缓存更快,但我找不到任何示例表明它更有用...
    • 如果我添加InitializingBean 继承,应用程序将失败并出现Name spring.liveBeansView.mbeanDomain is not bound in this Context. Returning null 错误...
    • 我在一个新问题中描述了我的问题:*.com/questions/17443854/…