Fetching some value from message.properties in Gra

2019-07-18 14:35发布

问题:

Want to fetch a value from message.properties file in grails in a job , how can I do that ??

My Job:

def execute() {
    // execute task
    List<String> emails = NayaxUser.findAllByEmailSent(false)*.username
    emails.each {emailAddress->
        mailService.sendMail {
            //todo: FETCH FROM MESSAGE.PROPERTIES
            to emailAddress
            from FETCH FROM MESSAGE.PROPERTIES
            subject FETCH FROM MESSAGE.PROPERTIES
            html body.toString()
        }
    }
}

回答1:

You can use:

g.message(code: 'my.message.code')
//or
g.message(code: 'my.message.code', args: [arg1, arg2])


回答2:

You can inject the messageSource to retrieve the message:

class MyJob {
    def messageSource

    def execute() {
        ...
        def message = messageSource.getMessage('message.code', ...)
        ...
    }
}

Here's the documentation for getMessage(); you need to provide a couple more method arguments, namely args (an Object[]) and a Locale.



回答3:

You can get a reference to the messageSource bean from anywhere using:

import org.codehaus.groovy.grails.commons.ApplicationHolder
import org.springframework.context.MessageSource

MessageSource messageSource = ApplicationHolder.application.mainContext.getBean('messageSource')

You can then get the messages themselves using the methods of the MessageSource interface.



回答4:

Just as an addition to above answers, there could be following places where you need to implement internationalisation or fetch the message from message bundles.

  1. views
  2. controllers
  3. services
  4. Filters
  5. Utility files(e.g. in util package or generalised exception message handling)
  6. Special files e.g. in Shiro security rest realms

Below are the elaborate usage scenarios:

  1. Views:- we have taglib available with message tag. Use this on views.

  2. controllers :- message method is by default available here and locale conversion is automatically handled. See enter link description here

  3. service: we may call taglibs inside services as below:

    def myCustomTaglib = grailsApplication.mainContext.getBean('com.custom.MyCustomTagLib');
    

Or inject messageSource bean as

def messageSource 

4.Filters / utility / Special files:- For these you may create something like below and then use it throughout.

 String i18nMessage(def input,String defaultMessage) {
                String[] languageCode = RequestContextHolder.currentRequestAttributes().request.getHeader("Accept-Language").split("-")
                Locale locale = languageCode.length == 2 ? new Locale(languageCode[0], languageCode[1]) : new Locale(languageCode[0])
                String message = defaultMessage
                try {
                    message = messageSource.getMessage(input.code,input?.args?.toArray(),locale)
                }catch (NoSuchMessageException nsme ){
                    log.info("No such error message--> ${nsme.getMessage()}")
                }
                return message
            }

Also, if you get exception below:

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

Then, you might need to add request listener to your web.xml

 <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
</listener>

Note: web.xml is not available by default, you need to generate it from template.

These are the most common places you might need message bundle conversions. Solution at point 4 would work in almost all cases. If you notice locale has been handled here manually which we could pass after fetching from requestHeader or request params optionally.

Hope it helps.