web-dev-qa-db-ja.com

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:そのようなプロパティはありません:クラスのmessageSource:org.codehaus.groovy.grails.support.MockApplicationContext

私はコントローラーでそのローカリゼーションを処理する方法がわかりません(サービスでも試しましたが、それはさらに複雑です)。

20

Grails 1.3.7を使用している場合は、メッセージソースを次のように宣言する必要があります。

def messageSource

このようにして、コントローラーに注入されます。 2.0では投稿したとおりにできると思いますが、それでも上記のように宣言してみる価値はあると思います。

23
Roberto Guerra

答えがあることは知っていますが、これが私の見解です。私はサービスをしました(他の人に触発されました)

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をモックできるため、他のサービスの単体テストも簡単になります。

ボーナスとして、サービスがWebリクエストコンテキストで実行されている場合、サービスは現在のWebリクエストの現在のロケールを見つけようとします。

14
sbglasius

上記の答えは私を助けませんでした。 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());
}

}
6
emihailov

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

6
chelder

公式の方法は実際には非常に簡単です。 公式ドキュメント は次のように述べています:

タグをメソッドとして呼び出すことができるため、コントローラーでメッセージを読み取るのは簡単です。

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")
2
Cristan

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...
    }
}
1
Shivam Pandey

以下のコードとHoldersを使用した動作を試しました。

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)
0
Pukhraj soni