Grails : Upload and Render File

16 / Apr / 2009 by Amit Jain 16 comments

Lets discuss how can we upload a file and store it in a database, along with that how do we render it on the gsp page. I am taking an example to upload and render the image in this blog, though the code would be same for any other file.

So Lets consider I have a domain class with the name Person

class Person {
    .
    .
    .
    bytes[] picture
    static constraints = {
        picture(size:0..5000000)  // to store files upto 5MB approx
    }
}

Once we have a field with a byte[] defined in the class then automatically its view is generated with a input tag of file type in html, which returns the MultipartFile object in the controller. MultipartFile provides various useful methods which can be used getBytes(), getSize(), getContentType(), getName() etc.

So as MultipartFile object returs the byte[] which is to be stored in a picture property of a person class, in the save action of the PersonController Lets see how we do it :

person.picture = params.picture
or
person.properties = params

//Now the person object holds the image and lets save it

person.save()

We are done with file uploading. Now to render the image/file, lets have a separate controller in a controller directory, where we would define the action to generate the image:

class ImageController {  def defaultAction ='show'

def show= {
    //loads the class with a name and assigns obj a new instance created of the same object
    def obj = Class.forName("${params.classname}",true,Thread.currentThread().contextClassLoader).newInstance();
    def object = obj.get( params.id )
    response.setContentType(params.mime)
    byte[] image = object."${params.fieldName}"
    response.outputStream << image
  }
}

Now where ever we want to display the image, we can just include the following tag:


Note : The above code can be dangerous as a hacker can modify the className and feildName in the query string and get the hidden information.
Hope this helped.

~Amit Jain~

amit@intelligrape.com

http://www.IntelliGrape.com/

FOUND THIS USEFUL? SHARE IT

comments (16)

  1. kshitija

    I create form and i want to save details of my form in file which i entered from front end how i do in grails

    Reply
  2. ANUJ

    Hi Amit
    i have uploaded the PDF file and saved into the database byte[] document), i want that the uploaded pdf should show on GSP inside the particular div. how can i do that? please help

    Reply
    1. Amit Jain

      Hi Anuj,

      For displaying file in a div, it looks like it is no different than image then. Can we not render this file as an image? See stackoverflow.com/questions/4502278/grails-displaying-created-image-in-gsp how can we do that. Let me know if this doesn’t work.
      Thanks,

      Reply
  3. Sumit

    Hi Amit i want to store image in file system it is working fine on local system but when i upload image on prod environment it show me error java.io.FileNotFoundException: . Could you help me please.
    Thanks

    Reply
  4. Vijay

    Hi Amit,

    Just wanted to mention, that image previews cannot be done in a cross browser fashion, using the approach suggested by you. IE will never allow the application to reference the local file, same applies for chrome. Only cross browser way of showing image previews is to use, ajax based file upload and then sending the image back as base64 encoded string.

    Hope that helps someone.

    Reply
  5. santosh

    @Amit Jain
    Thank you sir for your quick response. Can you post the code snippet or any example to show.I am novice to grails and don’t have experience with javascript.

    Reply
  6. Amit Jain

    Yes you can. For that you can use javascript to add “img” tag dynamically and keep its source as taken from file input box value. This script can be executed on lost focus of file input box.

    Reply
  7. amit

    Thanks Alessio & bald for bringing out the loopholes in the code. If you could find the solution then please share.
    And yes we need to provide the content type, which I have updated in the blog now.

    Reply
  8. bald

    Thanks Amit for showing how easy and fast is implementing (prototyping) file upload in Grails.

    Would be better in a real scenario to use a general domain class such as document, file or image? You can also save other useful information for categorizing (size, mime, etc)
    Also this type of controller action seems quite risky.

    Reply
  9. Alessio Spadaro

    Isn’t it a little dangerous? I.e. what if i call the controller specifying potentially dangerous Class/method combinations?
    Furthermore, how’s the client able to determine the content type without specifying it?

    Regards,
    Alessio

    Reply

Leave a comment -