Grails:如何从控制器或服务访问 i18n?
Posted
技术标签:
【中文标题】Grails:如何从控制器或服务访问 i18n?【英文标题】:Grails: How to access i18n from controller or service? 【发布时间】:2012-01-30 20:47:19 【问题描述】:我做了这个控制器,应该用来发送电子邮件。我需要访问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
我不知道如何在控制器中处理本地化(我也在服务中尝试过,但这更复杂)。
【问题讨论】:
不需要调用 g.message() 吗? 我为什么要这样做?我没有找到关于“g”的信息。 【参考方案1】:如果您使用的是 grails 1.3.7,则需要将消息源声明为:
def messageSource
这样它将被注入到您的控制器中。我认为在 2.0 中您可以按照您发布的方式进行操作,但即便如此,我认为还是值得尝试按照上述方式声明它。
【讨论】:
是的,这有帮助,谢谢。工作代码是:def messageSource public void sendEmail() String subject = message(code:"somemessagekey", args:[name]) ...
【参考方案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 的当前语言环境,假设该服务在 webrequest 上下文中运行。
【讨论】:
【参考方案3】:在 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
【讨论】:
def MessageSource messageSource 不应该是 MessageSource messageSource 还是 def messageSource?声明 def 和类是多余的。【参考方案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());
【讨论】:
如果你需要从另一个控制器调用一个控制器的方法,messageSource 将为空。 (至少对我来说)。所以,自己设置可能会很有趣。【参考方案5】:官方的方式其实很简单。 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")
【讨论】:
这个答案只对控制器有效。它在服务中不起作用。【参考方案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...
【讨论】:
【参考方案7】:我尝试了下面的代码及其使用 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)
【讨论】:
以上是关于Grails:如何从控制器或服务访问 i18n?的主要内容,如果未能解决你的问题,请参考以下文章