在你的项目中加入一个新的领域类:
class Message {
String code
Locale locale
String text
}
将以下行添加到您的resources.groovy:
// Place your Spring DSL code here
beans = {
messageSource(DatabaseMessageSource) {
messageBundleMessageSource = ref("messageBundleMessageSource")
}
messageBundleMessageSource(org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSource) {
basenames = "WEB-INF/grails-app/i18n/messages"
}
}
并将以下类添加到您的 src/groovy 文件夹中:
class DatabaseMessageSource extends AbstractMessageSource {
def messageBundleMessageSource
protected MessageFormat resolveCode(String code, Locale locale) {
Message msg = messageBundleMessageSource.resolveCode(code, locale)
def format
if(msg) {
format = new MessageFormat(msg.text, msg.locale)
}
else {
format = Message.findByCodeAndLocale(code, locale)
}
return format;
}
}
现在 grails 将尝试从消息包中解析消息。如果不可用,它将从数据库中查找。您可以添加一些错误处理,但如果所有消息至少在一个地方可用,则此版本有效。
有关更多详细信息,请参阅http://graemerocher.blogspot.com/2010/04/reading-i18n-messages-from-database.html。
resources.groovy中所做更改的一些细节:
在此文件中,您可以定义可注入的 groovy 类,只需定义一个与 resources.groovy 中定义的名称相同的变量即可包含这些类。例如。在此文件中,有messageSource 和messageBundleMessageSource,您可以将它们包含在任何控制器或服务文件中。如果定义了此变量,则会创建括号中的类的实例。
在这种情况下,我们会覆盖通用 messageSource 以使用我们的自定义实现 DatabaseMessageSource。所以 I18n 函数message 现在将使用我们的自定义实现。
由于我们的自定义实现需要检查message.properties-文件,我们将原始消息源保留在第二个bean中。通过在我们的自定义实现中定义这个实例,我们仍然可以使用旧的实现(因此以通常的方式查找消息)。