Search code examples
javagrailsgsp

gsp, image from array byte


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 ?


Solution

  • 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