Grails:从i18n消息属性中获取消息的最佳方式



我已经找到了一种从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")])

显然,这是一个更简单的版本,但我想知道哪种方式是首选的(最佳实践),以及两者的区别是什么。

控制器内部messageg.message可直接从ValidationTagLib获得。您的同事正在将一个对象ApplicationTagLib分配给变量g。我怀疑ApplicationTagLib是一个自定义类,不是由grails api提供的,至少在2.3.x.中没有

如果您在应用程序中除了控制器之外的任何位置都需要i18消息,那么您必须首先获得messageSource bean,或者您可以创建ValidationTagLib的新实例,然后在该实例上调用message()

除了上述答案之外,您可能还需要在以下地方实现国际化或从消息包中获取消息。

  1. 视图
  2. 控制器
  3. 服务
  4. 过滤器
  5. 实用程序文件(例如,在util包或通用异常消息处理中)
  6. 特殊文件,例如Shiro安全休息区

以下是详细的使用场景:

  1. 视图:-我们有带消息标签的标签库。在视图中使用此选项。

  2. controllers:-message方法在这里默认可用,并且自动处理区域设置转换。看看这个。

  3. 服务:我们可以在服务内部调用taglib,如下所示:

    def myCustomTaglib = grailsApplication.mainContext.getBean('com.custom.MyCustomTagLib');
    

或者注入messageSource bean作为

def messageSource 
  1. 过滤器/实用程序/特殊文件:-对于这些,你可以创建下面这样的东西,然后在整个过程中使用它。

    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或request params获取后传递(可选)。

希望能有所帮助。

最新更新