Kevin
Kevin

Reputation: 956

How to display image in grails GSP?

I'm still learning Grails and seem to have hit a stumbling block.

Here are the 2 domain classes:

class Photo {
    byte[] file 

    static belongsTo = Profile
}


class Profile {
    String fullName
    Set photos

    static hasMany = [photos:Photo]     
}

The relevant controller snippet:

class PhotoController {

    def viewImage = {

      def photo = Photo.get( params.id )
      byte[] image = photo.file 
      response.outputStream << image

    } 
} 

Finally the GSP snippet:

<img class="Photo" src="${createLink(controller:'photo', action:'viewImage', id:'profileInstance.photos.get(1).id')}" />

Now how do I access the photo so that it will be shown on the GSP? I'm pretty sure that profileInstance.photos.get(1).id is not correct.

Upvotes: 9

Views: 25739

Answers (6)

stitakis
stitakis

Reputation: 891

I´m learning grails too was searching for an example like this one. The GSP snipplet didn´t work for me. I resolved by replacing the single quotes around profileInstance.photos.get(1).id

<img class="Photo" src="${createLink(controller:'photo', action:'viewImage', id:'profileInstance.photos.get(1).id')}" />

with double quotes:

<img class="Photo" src="${createLink(controller:'photo', action:'viewImage', id:"profileInstance.photos.get(1).id")}" />

Now grails resolves the expression around the double quotes. Otherwise it takes it as string.

Upvotes: 1

leroy zhu
leroy zhu

Reputation: 1

id:'profileInstance.photos.get(1).id' should be id:profileInstance.photos.get(1).id. no quota

Upvotes: 0

Miguel Ping
Miguel Ping

Reputation: 18347

If you have a url for the image, you just have to make sure you return the appropriate anser in the controller:

  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;
  }

Upvotes: 4

Chii
Chii

Reputation: 14756

now, i actually think storing the photo as a binary blob in the database isnt the best solution - though you might have reasons why it needs to be done that way.

how about storing the name of the photo (and/or the path) instead? If name clashing issues are probable, use the md5 checksum of the photo as the name. Then the photo becomes a static resource, a simple file, instead of a more complicated and slower MVC request.

Upvotes: 2

Hates_
Hates_

Reputation: 68791

As it is a Set, if you want the first element, you will have to go:

profileInstance.photos.toArray()[0].id

or

profileInstance.photos.iterator().next()

Upvotes: 3

billjamesdev
billjamesdev

Reputation: 14640

My guess is you need to set the content type of the response stream. Something like:

response.ContentType = "image/jpeg"

This may or may not need to be before you stream to the response stream (can't imagine that it would matter). I'd just put it before the outputStream line in your code above.

Upvotes: 0

Related Questions