6

我希望对我在 Spring 中涉及属性文件的问题有所帮助。所以我的设置是这样的:

opto-mapping.properties – 它位于我的 src 文件夹中,包含我优化的资源的翻译,如下所示:

generic-min.css=4037119659.css

每次运行构建“优化”时都会更新此属性文件。然后我用

<fmt:setBundle basename="opto-mapping" />

在我想要的 jsp 中导入我的属性文件。然后使用以下方法引用内容:

<fmt:message key='generic-min.css' />

这一切都很好,除了属性文件需要重新加载 tomcat 重启。我不想在每次更新资源时都开始关闭网站。我希望属性文件每隔一段时间自动重新加载。

我确实尝试更新 spring-context.xml 中的现有 bean 以重新加载此属性文件,就像我对翻译所做的那样,但这没有奏效 - 很可能是因为 opto-mapping.properties 文件位置 - 但你看到它需要在该位置使用 fmt:setBundle 加载。

<bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="cacheSeconds">
            <value>1</value>
        </property>
        <property name="basenames">
            <list>
                <value>WEB-INF/translations/translations</value>
                <value>WEB-INF/classes/opto-mapping</value>
            </list>
        </property>
</bean>

在这个困难时期,我们将不胜感激任何帮助或正确方向的观点。

我希望这一切都有意义,并提前非常感谢!

G。

4

3 回答 3

5

谢谢你们的回复。我现在已经完成了这项工作,并认为我会分享财富。

因此,我将我的属性文件从 src 文件夹中移出到 WEB-INF/properties。

我更新了以下 bean 以加载属性文件:

<bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="cacheSeconds">
            <value>1</value>
        </property>
        <property name="basenames">
            <list>
                <value>WEB-INF/translations/translations</value>
                <value>WEB-INF/properties/opto-mapping</value>
            </list>
        </property>
    </bean>

现在,以前我使用 setBundle 加载到我的属性文件中,如下所示:

<fmt:setBundle basename="opto-mapping" />

但是我发现很明显我的属性文件没有被加载,因为我已经移动了它。但是由于我的 bean 设置,正在加载新的属性文件,但我的 setBundle 覆盖了它。

因此,解决方案是删除 setBundle,现在我的属性文件正在重新加载!

再次感谢!

于 2010-11-11T16:53:32.387 回答
4

Tomcat 不会重新加载类路径上的资源。这在javadoc中有说明ReloadableResourceBundleMessageSource

由于应用程序服务器通常会缓存从类路径加载的所有文件,因此有必要将资源存储在其他地方(例如,在 Web 应用程序的“WEB-INF”目录中)。否则类路径中文件的更改将不会反映在应用程序中。

这样的类路径位置包括WEB-INF/classes,并且不会被释放。

尝试移动opto-mapping.properties到其他地方(例如WEB-INF/messages),然后尝试。

于 2010-11-09T17:48:27.287 回答
1

您可以尝试一些事情。

<fmt:setBundle>最终会调用ResourceBundle.getBundle(String, Locale, ClassLoader),其中字符串将是您的基本名称,而类加载器将是Thread.currentThread().getContextClassLoader()。如果您使用的是 JDK 1.6,您可以尝试使用ResourceBundle.clearCache(ClassLoader)清除捆绑缓存。在 servlet 过滤器中执行此操作并将其与其他一些逻辑结合以确定何时应清除缓存是有意义的。

另一个角度是更直接地控制属性文件的加载和 JSTL 的配置。同样,使用过滤器(忽略异常处理):

ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader();
URL propsURL = ctxLoader.getResource("opto-mapping.properties");
URLConnection propsConn = propsURL.openConnection();
long propsLastModified = propsConn.getLastModified();
// decide if you want to reload...
propsConn.setUseCaches(false);
InputStream propsIn = propsConn.getInputStream();
ResourceBundle propsBundle = new PropertyResourceBundle(propsIn);
propsIn.close();
LocalizationContext propsCtx = new LocalizationContext(propsBundle);
ServletContext servletCtx = this.filterConfig.getServletContext();
Config.set(servletCtx, Config.FMT_LOCALIZATION_CONTEXT, propsCtx);

然后你可以<fmt:message>在你的页面中使用。您可以在JSTL APILocalizationContext中找到文档。Config

许多其他变体是可能的,但请务必查看 JDK 1.6 的更新ResourceBundle(包括ResourceBundle.Control)添加,记住“低级”API 的功能,URLConnection如通过其 API。

于 2010-11-09T20:04:41.787 回答