HTML5 includes a multiple
attribute on file inputs; when set, a user can select multiple files to upload for that input with a single Browse... dialog. Grails makes handling uploads from non-multiple file-inputs really easy. For example, here's an action that echoes the content of a file uploaded via an input named myfile
:
class MyController {
def echoSimple = {
def charset = (params.myfile?.contentType =~ /charset=([^;]+)/).
collect { it[1].trim() }.join('') ?: 'ISO-8859-1'
def content = new String(params.myfile?.bytes ?: ''.bytes, charset)
render contentType: params.myfile?.contentType ?: 'text/plain', text: content
}
}
Handling multiple file-inputs is still pretty easy, but instead of accessing file objects via the controller's params
map, you use the multiFileMap
property of the controller's request
property. File objects will be instances of spring's MultipartFile
interface; for multipart form posts, the request
property will be an instance of spring's MultipartRequest
interface. The multiFileMap
property is a map of file-input names to the list of MultipartFile
s uploaded by that input. So if you have a form like the following:
<form action="${g.createLink(controller:'my', action:'echoMultiple')}"
method="post" enctype="multipart/form-data">
<input type="file" name="myfile" multiple>
<button type="submit">Submit</button>
</form>
You can echo the content of all the files selected by the user with this action:
class MyController {
def echoMultiple = {
def content = request.multiFileMap?.myfile?.collect { file ->
def charset = (file.contentType =~ /charset=([^;]+)/).
collect { it[1].trim() }.join('') ?: 'ISO-8859-1'
new String(file.bytes, charset)
}?.join('\n') ?: ''
render contentType: 'text/plain', text: content
}
}
(Note that while other browsers have supported the multiple
attribute for some time, no version of IE currently supports it — although it should be supported in IE 10.)