Grails Goodness: Accessing Resources with Resource and ResourceLocator
Grails uses Spring and we can piggyback on the Spring support for resource loading to find for examples files in the classpath of our application. We can use the Spring org.springframework.core.io.Resource
or org.springframework.core.io.ResourceLoader
interface to find resources in our application.
And since Grails 2.0 we can also use the org.codehaus.groovy.grails.core.io.ResourceLocator
interface. In our code we can use the grailsResourceLocator
service which implements the ResourceLocator
interface. We must inject the grailsResourceLocator
service into our code and we use the method findResourceForURI(String)
to find a resource. The advantage of the grailsResourceLocator
service is that it knows about a Grails application. For example resources in plugins can also be accessed.
First we look at a sample Grails service with a Resource
property with the name template
. In our code we get the actual resource using the getURL()
method. The value of the Resource
property we set in grails-app/conf/Config.groovy
. We rely on the automatic conversion of properties of Spring so we can use a value like classpath:filename.txt
and it will be converted to a Resource
implementation.
package com.mrhaki.templates import groovy.text.SimpleTemplateEngine import org.springframework.core.io.Resource class MessageService { Resource template String followUpMessage(final String user, final String subject) { final Map binding = [user: user, subject: subject] final SimpleTemplateEngine templateEngine = new SimpleTemplateEngine() templateEngine.createTemplate(template.URL).make(binding) } }
In grails-app/conf/Config.groovy
we define:
... beans { messageService { template = 'classpath:/com/mrhaki/templates/mail.template' } } ...
If we use the grailsResourceLocator
we get the following service implementation:
package com.mrhaki.templates import groovy.text.SimpleTemplateEngine class MessageService { def grailsResourceLocator String template String followUpMessage(final String user, final String subject) { final Resource template = grailsResourceLocator.findResourceForURI(template) final Map binding = [user: user, subject: subject] final SimpleTemplateEngine templateEngine = new SimpleTemplateEngine() templateEngine.createTemplate(template.URL).make(binding) } }
Code written with Grails 2.2.4