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