Grails:如何从控制器或服务访问i18n?

时间:2011-12-30 22:33:22

标签: grails

我制作了这个控制器,用于发送电子邮件。我需要访问i18n才能发送本地化的电子邮件。

class MailController {

    MessageSource messageSource 

    static transactional = false

    public void sendEmail() {
        String name = "some name..."
        String subject = message(code:"somemessagekey", args:[name])
        // do some fancy stuff here...
    }
}

然后有i18n文件(位于i18n文件夹中):

file name: messages.properties
content: somemessagekey = Blabla {0} - blablabla

运行之后,它会抛出(在集成测试中):

  

groovy.lang.MissingPropertyException:没有这样的属性:messageSource   for class:org.codehaus.groovy.grails.support.MockApplicationContext

我没有想法如何处理控制器中的本地化(我也在服务中尝试过它,但这更复杂)。

7 个答案:

答案 0 :(得分:23)

如果您使用的是grails 1.3.7,则需要将消息源声明为:

def messageSource

这样它就会被注入你的控制器。我认为在2.0中您可以按照发布的方式进行,但即便如此,我认为值得尝试按上述方式声明它。

答案 1 :(得分:14)

我知道有答案,但这是我的看法。我提供了服务(受其他人启发)

import org.springframework.web.servlet.i18n.SessionLocaleResolver
import org.springframework.context.MessageSource

class I18nService {

    boolean transactional = false

    SessionLocaleResolver localeResolver
    MessageSource messageSource

    /**
     *
     * @param msgKey
     * @param defaultMessage default message to use if none is defined in the message source
     * @param objs objects for use in the message
     * @return
     */
    def msg(String msgKey, String defaultMessage = null, List objs = null) {

        def msg = messageSource.getMessage(msgKey,objs?.toArray(),defaultMessage,localeResolver.defaultLocale)

        if (msg == null || msg == defaultMessage) {
            log.warn("No i18n messages specified for msgKey: ${msgKey}")
            msg = defaultMessage
        }

        return msg
    }

    /**
     * Method to look like g.message
     * @param args
     * @return
     */
    def message(Map args) {
        return msg(args.code, args.default, args.attrs)
    }
}

现在,在服务中注入i18nService,你就可以了!这也使得对其他服务的单元测试变得轻而易举,因为您可以模拟i18nService

作为奖励,该服务将尝试查找当前webrequest的当前区域设置,该服务在webrequest上下文中运行。

答案 2 :(得分:6)

在Grails 2.2.3中它应该有效:

import org.springframework.context.MessageSource
...
def MessageSource messageSource
...
String subject = messageSource.getMessage("somemessagekey", [name], null)
...

参考链接以及更多可能性:http://static.springsource.org/spring/docs/2.0.8/api/org/springframework/context/MessageSource.html

答案 3 :(得分:5)

上面的答案对我没有帮助。 我使用的是Grails 3.0.1,下面的解决方案对我很有用

import org.springframework.context.i18n.LocaleContextHolder as LCH
import grails.util.Holders;

class MyService{

def messageSource = Holders.getGrailsApplication().getParentContext();

public String MyMethod()
{
    String message = messageSource.getMessage("code",args,LCH.getLocale());
}

}

答案 4 :(得分:2)

官方方式实际上非常简单。 The official documentation声明如下:

  

在控制器中读取消息很简单,因为您可以调用标记   作为方法:

def show() {
    def msg = message(code: "my.localized.content", args: ['Juan', 'lunes'])
}
     

tag libraries可以使用相同的技术,但如果你的标签   库使用自定义namespace,然后您必须为呼叫添加前缀   与g.

def myTag = { attrs, body ->
    def msg = g.message(code: "my.localized.content", args: ['Juan', 'lunes'])
}

此外,请注意,如果您的翻译不使用参数,则不提供参数:

def msg = message(code: "my.localized.content")

答案 5 :(得分:1)

我正在使用grails 3.x.Injected messageSource

  

org.springframework.context.MessageSource

并使用

String getMessage(String code, Object[] args, String defaultMessage, Locale locale);

此方法。将代码修改为

class MailController {

    MessageSource messageSource 

    static transactional = false

    public void sendEmail() {
        String name = "some name..."
        String subject = messageSource.getMessage('somemessagekey', [name], '', null)
        // do some fancy stuff here...
    }
}

答案 6 :(得分:0)

我尝试了下面的代码,并使用Holders工作。

super