Accessing Application Files from Code in Grails

March 13th 2016 Grails

In web applications, server-side code will sometimes need access to additional external resources, such as font files, certificates etc. If you want to distribute them as part of your application, the path to the corresponding files will need to be determined at runtime, as it depends on the deployment location. As far as I could determine, there are three options, where to put such files.

Static Client Files

If the files should be accessible both from the server and the client (browser), you should put them into the web-app directory in the root of your project (along with the grails-app and src folders). This is the location for the static client side files that don't need to be processed by the Grails Asset Pipeline and hence are not placed in the grails-app\assets folder.

You'll need to have the Grails ResourceLocator injected into your controller or service to gain access to these files:

class MyController {

    ResourceLocator grailsResourceLocator // injected during initialization

    def action() {

        // ...

        def resource = grailsResourceLocator.findResourceForURI('/static.json')
        def path = resource.file.path // absolute file path
        def inputStream = resource.inputStream // input stream for the file

       // ...
    }

    // ...
}

Make sure you always pass in the absolute URI of the path (starting with a /), or the file won't be found.

Server-Only Files

For the files that are specific to the server and shouldn't be accessible from the browser, you should put them in the grails-app/conf folder. Any files placed in that folder will be copied to the root of your application during build. This means they will be accessible as regular Java resources:

def resource = this.class.classLoader.getResource('conf.json')
def path = resource.file // absolute file path
return resource.openStream() // input stream for the file

Notice that there's no leading / in this case.

Alternatively, you can also put these files into src/main/resources folder, if you don't want to pollute your conf folder with files that are not really configuration files. The code to access them will still be the same. Thanks to Gregor for bringing this option to my attention.

Copyright
Creative Commons License