Grails Goodness: Render Binary Output with the File Attribute
Since Grails 2 we can render binary output with the render()
method and the file
attribute. The file
attribute can be assigned a byte[]
, File
, InputStream
or String
value. Grails will try to determine the content type for files, but we can also use the contentType
attribute to set the content type.
In the following controller we find an image in our application using grailsResourceLocator
. Then we use the render()
method and the file
and contenType
attributes to render the image in a browser:
package com.mrhaki.render
import org.codehaus.groovy.grails.core.io.ResourceLocator
import org.springframework.core.io.Resource
class ImageController {
ResourceLocator grailsResourceLocator
def index() {
final Resource image = grailsResourceLocator.findResourceForURI('/images/grails_logo.png')
render file: image.inputStream, contentType: 'image/png'
}
}
The following screenshots shows the output of the index()
action in a web browser:
We can use the fileName
attribute to set a filename for the binary content. This will also set a response header with the name Content-Disposition
with a the filename as value. Most browser will then automatically download the binary content, so it can be saved on disk. Grails will try to find the content type based on the extension of the filename. A map of extensions and content type values is defined in the grails-app/conf/Config.groovy
configuration file. We can add for example for png
a new key/value pair:
...
grails.mime.types = [
all: '*/*',
png: 'image/png',
atom: 'application/atom+xml',
css: 'text/css',
csv: 'text/csv',
form: 'application/x-www-form-urlencoded',
html: ['text/html','application/xhtml+xml'],
js: 'text/javascript',
json: ['application/json', 'text/json'],
multipartForm: 'multipart/form-data',
rss: 'application/rss+xml',
text: 'text/plain',
xml: ['text/xml', 'application/xml']
]
...
In our controller we can change the code so we use the fileName
attribute:
package com.mrhaki.render
import org.codehaus.groovy.grails.core.io.ResourceLocator
import org.springframework.core.io.Resource
class ImageController {
ResourceLocator grailsResourceLocator
def index() {
final Resource image = grailsResourceLocator.findResourceForURI('/images/grails_logo.png')
render file: image.inputStream, fileName: 'logo.png'
}
}
Code written with Grails 2.2.4