8.1.9 Uploading Files

Programmatic File Uploads

Grails supports file uploads using Spring’s MultipartHttpServletRequest interface. The first step for file uploading is to create a multipart form like this:

  1. Upload Form: <br />
  2. <g:uploadForm action="upload">
  3. <input type="file" name="myFile" />
  4. <input type="submit" />
  5. </g:uploadForm>

The uploadForm tag conveniently adds the enctype="multipart/form-data" attribute to the standard <g:form> tag.

There are then a number of ways to handle the file upload. One is to work with the Spring MultipartFile instance directly:

  1. def upload() {
  2. def f = request.getFile('myFile')
  3. if (f.empty) {
  4. flash.message = 'file cannot be empty'
  5. render(view: 'uploadForm')
  6. return
  7. }
  8. f.transferTo(new File('/some/local/dir/myfile.txt'))
  9. response.sendError(200, 'Done')
  10. }

This is convenient for doing transfers to other destinations and manipulating the file directly as you can obtain an InputStream and so on with the MultipartFile interface.

File Uploads through Data Binding

File uploads can also be performed using data binding. Consider this Image domain class:

  1. class Image {
  2. byte[] myFile
  3. static constraints = {
  4. // Limit upload file size to 2MB
  5. myFile maxSize: 1024 * 1024 * 2
  6. }
  7. }

If you create an image using the params object in the constructor as in the example below, Grails will automatically bind the file’s contents as a byte[] to the myFile property:

  1. def img = new Image(params)

It’s important that you set the size or maxSize constraints, otherwise your database may be created with a small column size that can’t handle reasonably sized files. For example, both H2 and MySQL default to a blob size of 255 bytes for byte[] properties.

It is also possible to set the contents of the file as a string by changing the type of the myFile property on the image to a String type:

  1. class Image {
  2. String myFile
  3. }

Increase Upload Max File Size

Grails default size for file uploads is 128000 (~128KB). When this limit is exceeded you’ll see the following exception:

  1. org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException

You can configure the limit in your application.yml as follows:

grails-app/conf/application.yml

  1. grails:
  2. controllers:
  3. upload:
  4. maxFileSize: 2000000
  5. maxRequestSize: 2000000

maxFileSize = The maximum size allowed for uploaded files.

maxRequestSize = The maximum size allowed for multipart/form-data requests.

You should keep in mind OWASP recommendations - Unrestricted File Upload

Limit the file size to a maximum value in order to prevent denial of service attacks.

These limits exist to prevent DoS attacks and to enforce overall application performance