代码之家  ›  专栏  ›  技术社区  ›  mbrevoort

在Grails中,我如何为locale获取messages.properties的configObject?

  •  3
  • mbrevoort  · 技术社区  · 14 年前

    在圣杯,我想得到一个 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 回复  |  直到 11 年前
        1
  •  1
  •   mbrevoort    14 年前

    我找到了一个可行的解决方案,可以根据当前的区域设置直接从适当的消息属性包中加载属性。

    看起来我可以用相对于应用程序根目录的路径加载文件。这对于在本地运行嵌入式Tomcat和as a war(“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
    
        2
  •  0
  •   Tony the Tech    11 年前

    我知道这很古老,但我来这里是为了做同样的事情。使用 LocaleContextHolder 尽管我决定使用 RequestContextUtils . 在我的实现中,我想使用Java自己的本地化解决策略。这里是(目前使用的是Grails2.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 Marshaller序列化这个东西时,它不是您想要的。把这个加到你的 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/Simult/Cclipse MasaGeStices。

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

    在客户中,转到 myapp/i18n/strings 您将看到这样的JSON:

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

    因此,使用这个解决方案,您可以将要发送到JavaScript端进行查找的所有字符串和唯一字符串放在GrailsI18n文件夹中。一个警告是这里的字符串对g:message不可用,反之亦然。如果有人能想出一个解决方案来在i18n中找出一个基名,我想看看。

        3
  •  -1
  •   Dónal    14 年前

    的实现类型 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中的一个bug而调用它。它还对 mesageSource .