Grails:从 i18n 消息属性获取消息的首选方式
Grails: Most preferred way to get message from i18n message properties
我已经找到了一种从 i18n 消息属性(控制器外部)获取消息的方法
def messageSource = Holders.grailsApplication.mainContext.getBean 'messageSource'
....
errorMessages << [field: "transactionDate", message: messageSource.getMessage("transactionDate.require.message", null ,null)]
但后来在回顾我同事的作品时,我发现他们使用不同的方式..
def g = new ApplicationTagLib()
errorMessages.add([field: "exchangeRate", message: g.message(code: "exchangeRate.max.message")])
显然,这是一个更简单的版本,但我想知道首选哪种方式(最佳实践)以及两者之间的区别是什么。
Inside a Controller message
和 g.message
可直接从 ValidationTagLib
获得。您的同事正在将 ApplicationTagLib
的对象分配给变量 g
。我怀疑 ApplicationTagLib
是自定义 class 而不是由 grails api 提供,至少在 2.3.x.
中没有
如果您在应用程序中除了控制器之外的任何地方都需要 i18 消息,那么您必须先获取 messageSource
bean,或者您可以创建一个新的 ValidationTagLib
实例,然后调用 message()
在那个实例上。
作为对上述答案的补充,可能有以下地方需要实现国际化或从消息包中获取消息。
- 观看次数
- 控制器
- 服务
- 过滤器
- 实用程序文件(例如在 util 包或通用异常消息处理中)
- 特殊文件,例如在 Shiro 安全休息区
下面是详细的使用场景:
查看次数:- 我们有带有消息标签的标签库。在视图上使用它。
controllers :- message 方法在此处默认可用,并且会自动处理语言环境转换。 See this.
服务:我们可以在服务内部调用标签库,如下所示:
def myCustomTaglib = grailsApplication.mainContext.getBean('com.custom.MyCustomTagLib');
或者将 messageSource bean 注入为
def messageSource
过滤器/实用程序/特殊文件:- 对于这些,您可以创建如下所示的内容,然后在整个过程中使用它。
String i18nMessage(def input,String defaultMessage) {
String[] languageCode = RequestContextHolder.currentRequestAttributes().request.getHeader("Accept- Language").split("-")
Locale locale = languageCode.length == 2 ? new Locale(languageCode[0], languageCode[1]) : new Locale(languageCode[0])
String message = defaultMessage
try {
message = messageSource.getMessage(input.code,input?.args?.toArray(),locale)
}catch (NoSuchMessageException nsme ){
log.info("No such error message--> ${nsme.getMessage()}")
}
return message
}
此外,如果您遇到以下异常:
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
然后,您可能需要将请求侦听器添加到您的 web.xml
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
注意: web.xml默认不可用,需要模板生成。
这些是您可能需要消息包转换的最常见位置。
第 4 点的解决方案几乎适用于所有情况。如果您注意到语言环境已在此处手动处理,我们可以在从 requestHeader 或可选的请求参数中获取后传递。
希望对您有所帮助。
我已经找到了一种从 i18n 消息属性(控制器外部)获取消息的方法
def messageSource = Holders.grailsApplication.mainContext.getBean 'messageSource'
....
errorMessages << [field: "transactionDate", message: messageSource.getMessage("transactionDate.require.message", null ,null)]
但后来在回顾我同事的作品时,我发现他们使用不同的方式..
def g = new ApplicationTagLib()
errorMessages.add([field: "exchangeRate", message: g.message(code: "exchangeRate.max.message")])
显然,这是一个更简单的版本,但我想知道首选哪种方式(最佳实践)以及两者之间的区别是什么。
Inside a Controller message
和 g.message
可直接从 ValidationTagLib
获得。您的同事正在将 ApplicationTagLib
的对象分配给变量 g
。我怀疑 ApplicationTagLib
是自定义 class 而不是由 grails api 提供,至少在 2.3.x.
如果您在应用程序中除了控制器之外的任何地方都需要 i18 消息,那么您必须先获取 messageSource
bean,或者您可以创建一个新的 ValidationTagLib
实例,然后调用 message()
在那个实例上。
作为对上述答案的补充,可能有以下地方需要实现国际化或从消息包中获取消息。
- 观看次数
- 控制器
- 服务
- 过滤器
- 实用程序文件(例如在 util 包或通用异常消息处理中)
- 特殊文件,例如在 Shiro 安全休息区
下面是详细的使用场景:
查看次数:- 我们有带有消息标签的标签库。在视图上使用它。
controllers :- message 方法在此处默认可用,并且会自动处理语言环境转换。 See this.
服务:我们可以在服务内部调用标签库,如下所示:
def myCustomTaglib = grailsApplication.mainContext.getBean('com.custom.MyCustomTagLib');
或者将 messageSource bean 注入为
def messageSource
过滤器/实用程序/特殊文件:- 对于这些,您可以创建如下所示的内容,然后在整个过程中使用它。
String i18nMessage(def input,String defaultMessage) { String[] languageCode = RequestContextHolder.currentRequestAttributes().request.getHeader("Accept- Language").split("-") Locale locale = languageCode.length == 2 ? new Locale(languageCode[0], languageCode[1]) : new Locale(languageCode[0]) String message = defaultMessage try { message = messageSource.getMessage(input.code,input?.args?.toArray(),locale) }catch (NoSuchMessageException nsme ){ log.info("No such error message--> ${nsme.getMessage()}") } return message }
此外,如果您遇到以下异常:
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
然后,您可能需要将请求侦听器添加到您的 web.xml
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
注意: web.xml默认不可用,需要模板生成。
这些是您可能需要消息包转换的最常见位置。 第 4 点的解决方案几乎适用于所有情况。如果您注意到语言环境已在此处手动处理,我们可以在从 requestHeader 或可选的请求参数中获取后传递。
希望对您有所帮助。