在Grails中,如何获取locale的ConfigObject of messages.properties?

时间:2010-08-19 23:27:08

标签: java grails internationalization groovy

在Grails中,我想获得对当前语言环境的已加载消息属性文件的ConfigObject引用。或者某种方式可以轻松地读取消息属性(对于当前语言环境)的全部内容。我想将其转换为JSON并将其发送回客户端,以用于通过javascript查找字符串。

本质上我想做这样的事情:

def props = new java.util.Properties()
props.load(... the right message bundle ...);
def messages = new ConfigSlurper().parse(props)
render messages as JSON

我假设有一种更优雅的方式来做到这一点。 messageSource接口仅允许您获取特定键的消息。我想要整个资源包,所以我可以将它转换为JSON。

3 个答案:

答案 0 :(得分:1)

我找到了一个可行的解决方案,即根据当前语言环境直接从正确的消息属性包中加载属性。

看起来我只能使用相对于应用程序根目录的路径加载文件。这适用于在本地运行嵌入式tomcat和战争('grails run-app'和'grails run-war')但我没有测试部署到容器以了解路径是否将被正确解析。 / p>

这是我的测试控制器:

import grails.converters.*
import org.springframework.context.i18n.LocaleContextHolder as LCH 

class I18nController {

    def index = {
        def locale = LCH.getLocale().toString();
        def langSuffix = ( locale == "en" ) ? "" : "_${locale}" 
        def props = new java.util.Properties()
        props.load( new FileInputStream( "grails-app/i18n/messages${langSuffix}.properties" ) )
        render ( new ConfigSlurper().parse(props) ) as JSON
    }

}

可以像:

一样访问
http://localhost:8080/myapp/i18n
http://localhost:8080/myapp/i18n?lang=es
http://localhost:8080/myapp/i18n?lang=en

答案 1 :(得分:0)

我知道这已经过时了,但我来到这里寻找完全相同的事情。尽管我决定使用LocaleContextHolder,但使用RequestContextUtils获取所需的区域设置是一个很好的起点。在我的实现中,我想使用java自己的语言环境解析策略。所以这里(目前使用grails 2.1.2):

// Controller
import org.springframework.web.servlet.support.RequestContextUtils
import grails.converters.JSON


class I18nController {
    def strings() {
    ResourceBundle clientMessages = ResourceBundle.getBundle("com.example.ClientMessages",
        RequestContextUtils.getLocale(request),
        Thread.currentThread().contextClassLoader)
    render clientMessages as JSON
    }
}

当你使用默认的JSON编组器序列化这个东西时,它不是你想要的。因此,请将其添加到BootStrap.groovy闭包内的init

    // JSON Marshaller to serialize ResourceBundle to string table.
    JSON.registerObjectMarshaller(ResourceBundle) { bundle ->
        def returnObject = [:]
        bundle.keys.each {
            returnObject."${it}" = bundle.getString(it)
        }
        returnObject
    }

最后,将您要发送的资源放入类路径中的javascript客户端。在我的示例中,这些将放在src / java / com / example / ClientMessages.properties中。

size.small=Small
size.wide=Wide
size.large=Large

在客户端,转到myapp/i18n/strings,你会看到像这样的JSON:

{"size.small":"Small","size.wide":"Wide","size.large":"Large"}

因此,使用此解决方案,您将所有和仅要发送的字符串放到javascript端进行查找,并将其他所有内容放在grails i18n文件夹中。需要注意的是,此处的字符串不适用于g:message,反之亦然。如果有人能找到解决方案在i18n中为此目的单独输出一个基本名称,我希望能够看到它。

答案 2 :(得分:-1)

MessageSource的实施类型为org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSource。也许这个类(或其中一个父母)有方法,这将允许您获得对整个Properties集的引用。

以下看起来可能有用(虽然我还没有测试过):

// Get a reference to the message Source either via dependency injection or looking-up
// the bean in the application context
def messageSource
Properties messages = messageSource.getProperties("messages.properties").properties
// Now convert the Properties instance to JSON using your favorite Java-JSON library

这不是一个很好的解决方案,因为getProperties(filename)方法受到保护,所以你不应该调用它,但是你可以因为Groovy中的错误而调用它。它还对mesageSource的实现类型做了一些隐含的假设。