2008-11-03 20 views
9

Todavía estoy aprendiendo Grails y parece que he topado con un obstáculo.¿Cómo mostrar la imagen en grails GSP?

Aquí son las clases 2 de dominio:

class Photo { 
    byte[] file 

    static belongsTo = Profile 
} 


class Profile { 
    String fullName 
    Set photos 

    static hasMany = [photos:Photo]  
} 

El fragmento controlador relevante:

class PhotoController { 

..... 
    def viewImage = { 

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

    } 
...... 
} 

Finalmente el fragmento de GSP:

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

Ahora, ¿cómo accedo a la foto para que se muestre en el GSP? Estoy bastante seguro de que profileInstance.photos.get (1) .id no es correcto. ¡¡Gracias!!

+0

¿Has probado esto? Debería hacer que se llame a 'viewImage' con id = 1, refiriéndose a una instancia de Photo, suponiendo que haya un 'profileInstance' en el alcance.Es posible que deba ajustar el tipo de contenido de respuesta ¿Está preguntando cómo seleccionar _que foto muestra? –

+0

Espero mostrar la primera foto en el conjunto, gracias. – Walter

Respuesta

3

Como se trata de un conjunto, si desea que el primer elemento, se le tiene que ir:

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

o

profileInstance.photos.iterator().next() 
+0

Sí, la/photo/viewImage/{anyPhotoId} muestra una foto correctamente. En realidad, creo que utilicé un Set en lugar de ArrayList. ¿Es esto la causa del problema? ¡Gracias! – Walter

+0

@Walter - Ah sí. He modificado mi respuesta. –

0

Mi conjetura es que necesita para establecer el tipo de contenido del flujo de respuesta. Algo así como:

response.ContentType = "image/jpeg" 

Esto puede o no puede tener que ser antes de transmitir a la secuencia de respuesta (no se puede imaginar que sería materia). Lo pondría antes de la línea outputStream en su código anterior.

+0

Probé esto y no parece requerir la configuración de contentype. Tks. – Walter

2

ahora, de hecho creo que almacenar la foto como un blob binario en la base de datos no es la mejor solución, aunque es posible que tenga razones por las que debe hacerse de esa manera.

¿qué tal almacenar el nombre de la foto (y/o la ruta) en su lugar? Si los problemas de coincidencia de nombres son probables, utilice la suma de comprobación md5 de la foto como nombre. Luego, la foto se convierte en un recurso estático, un archivo simple, en lugar de una solicitud MVC más complicada y lenta.

+0

Esto podría ser una opción. Tendré que explorarlo más. ¡Gracias! – Walter

+1

¿Qué hay de asegurar esa imagen? Si usa una URL directa para el archivo, pierde la capacidad (o hace que sea mucho más difícil) de proteger la imagen para usuarios/roles específicos. – billjamesdev

+0

@ bill: supongo que depende de los requisitos. La seguridad tendrá un costo, y mi método es un poco más difícil de asegurar (no imposible, pero probablemente sea más sencillo usar las sugerencias de otros si la seguridad es importante). – Chii

4

Si tiene una URL de la imagen, sólo hay que asegurarse de que devuelva el Anser apropiado en el controlador:

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

Identificación: 'profileInstance.photos.get (1) .id' debería ser id: profileInstance.photos.get (1) .id. sin cuota

1

Estoy aprendiendo a aplicar grails también estaba buscando un ejemplo como este. El snipplet GSP no funcionó para mí. I resuelve al sustituir las comillas simples alrededor de profileInstance.photos.get (1) .id

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

con comillas dobles:

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

Ahora Grails resuelve la expresión alrededor de los dobles comillas. De lo contrario, lo toma como una cadena.

Cuestiones relacionadas