繁体   English   中英

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

[英]In Grails, how can I get a ConfigObject of messages.properties for locale?

在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。

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

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

这是我的测试控制器:

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

我知道这是旧的,但我来到这里寻找完全相同的事情。 使用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编组器序列化这个东西时,它不是你想要的。 所以将它添加到init闭包内的BootStrap.groovy

    // 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中为此目的单独输出一个基本名称,我希望看到它。

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的实现类型做了一些隐含的假设。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM