Grails: как получить доступ к i18n с контроллера или службы - PullRequest
20 голосов
/ 31 декабря 2011

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

У меня нет идей, как справитьсяэта локализация в контроллере (я тоже пробовал в сервисе, но это еще сложнее).

Ответы [ 7 ]

23 голосов
/ 31 декабря 2011

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

def messageSource

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

14 голосов
/ 07 июля 2013

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

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

В качестве бонуса служба будет пытаться найти текущую локаль для текущего веб-запроса, при условии, что служба работает в контексте веб-запроса.

6 голосов
/ 06 июля 2013

В 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

5 голосов
/ 21 марта 2016

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

}
2 голосов
/ 24 июня 2016

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

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

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

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

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

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

def msg = message(code: "my.localized.content")
1 голос
/ 01 декабря 2017

Я использую Граальс 3.x.Введено 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...
    }
}
0 голосов
/ 04 июня 2018

Я попробовал приведенный ниже код и его работа с использованием держателей.

def messageSource = Holders.getGrailsApplication().getMainContext().getBean("messageSource")

String errorMesssage = messageSource.getMessage('validation.error.catalogue.not.found', null, messageSource.getMessage(
                        'validation.error.catalogue.not.found', null, 'No Content found for the Reserved Instance Plan Catalogue', locale), locale)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...