Подтвердить что ты не робот

Grails: Как получить доступ к i18n от контроллера или службы?

Я сделал этот контроллер, который должен использоваться для отправки электронных писем. Мне нужно получить доступ к 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: No such property: messageSource for class: org.codehaus.groovy.grails.support.MockApplicationContext

Я не в курсе, как обрабатывать эту локализацию в контроллере (я также пробовал его в службе, но это еще сложнее).

4b9b3361

Ответ 1

Если вы используете grails 1.3.7, вам нужно объявить источник сообщения как:

def messageSource

Таким образом, он будет введен в ваш контроллер. Я думаю, что в 2.0 вы можете сделать это так, как вы разместили, но это так, я думаю, стоит попробовать объявить это, как указано выше.

Ответ 2

Я знаю, что есть ответ, но здесь я беру на это. Я сделал услугу (вдохновил других)

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.

Ответ 4

Ответ выше не помог мне. Я использую 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());
}

}

Ответ 5

Официальный способ на самом деле довольно прост. В официальной документации указано следующее:

Простое чтение сообщений в контроллере, так как вы можете вызывать теги как методы:

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

Такую же технику можно использовать в тегах библиотеки, но если ваш тег библиотека использует пользовательский namespace, тогда вы должны префикс вызова с g.:

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

Также обратите внимание, чтобы не предоставлять аргументы, когда ваш перевод не использует аргументы:

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

Ответ 6

Я использую 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...
    }
}