0

I have a JDO class and a helper class Image to store images within a byte array

JDO class:

@PersistenceCapable
class Recipe{

    @PrimaryKey
        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
        private Long key

        @Persistent
        private String description

        @Persistent(serialized = "true")
        private Image image;
}

Image class:

class Image implements Serializable {

    private byte[] content
    private String filename
    private String mimeType
}

In the gsp page I iterate through the recipes and want to show the images. I could do a controller like this to get the image src.

 def viewImage= {
    //retrieve photo code here
    response.setHeader("Content-disposition", "attachment; filename=${photo.name}")
    response.contentType = photo.fileType //'image/jpeg' will do too
    response.outputStream << photo.file //'myphoto.jpg' will do too
    response.outputStream.flush()
    return;
  }

But this way I have to send the key of the recipe to this controller and load the image again from the datastore. (I already have loaded it actually. But I think I can not send this data to the controller. Can I ?) Is there not a more convenient way to show the image from a byte array in gsp page ?

mjspier
  • 6,386
  • 5
  • 33
  • 43
  • 1
    Looks like duplicate of http://stackoverflow.com/questions/4502278/grails-displaying-created-image-in-gsp/4502403 to me. My answer there could help ;) – Victor Sergienko Mar 28 '11 at 08:32
  • Hi Victor. Thanks for the comment. I didn't saw you suggestion in this issue. But this looks like exactly what I was searching for. Going to try this out when I'm home. Thanks – mjspier Mar 28 '11 at 08:42
  • So many kind words, not a single upvote xD – Victor Sergienko Mar 28 '11 at 09:04

1 Answers1

1

I have a similar usecase here, a File domain class holding a byte[] and meta information for uploaded files. To download the file, I'm using:

def fileDownload = {
    long id = params.id as long
    def file = File.get(id)
    assert file
    def fileName = URLEncoder.encode(file.name)
    response.addHeader("content-disposition", "attachment;filename=$fileName")
    response.contentType = file.contentType
    response.contentLength = file.data.size()
    response.outputStream << file.data
}

Regarding reloading the file over and over I would not care too much, Hibernate 2nd level caching cares about it. If you still have a good reason for not loading the file in the download request, you might store it into the http session in a previous call. The downside of storing this in the http session:

  • in case of many concurrent sessions, high memory consumption
  • you'll see weird exceptions from Hibernate (be sure for that!)
  • everything stored in the http session must be serializable
Stefan Armbruster
  • 39,465
  • 6
  • 87
  • 97