2008-11-03 12 views
9

Wciąż uczę się Graalsa i wydaje mi się, że uderzyłem w przeszkodę.Jak wyświetlić obraz w grze GSP?

Oto Klasy 2 domeny:

class Photo { 
    byte[] file 

    static belongsTo = Profile 
} 


class Profile { 
    String fullName 
    Set photos 

    static hasMany = [photos:Photo]  
} 

Odpowiedni fragment kontroler:

class PhotoController { 

..... 
    def viewImage = { 

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

    } 
...... 
} 

końcu fragment GSP:

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

Jak mogę uzyskać dostęp do zdjęcia, aby było widoczne na GSP? Jestem całkiem pewien, że profileInstance.photos.get (1) .id nie jest poprawny. Dzięki!!

+0

Czy próbowałeś tego? Powinno to spowodować, że "viewImage" zostanie wywołany z id = 1, odwołując się do instancji Photo przy założeniu, że w zasięgu jest "profilInstance".Może być konieczne dostosowanie typu zawartości odpowiedzi: Czy pytasz, jak wybrać _, w którym wyświetlane jest zdjęcie? –

+0

Mam nadzieję, że wyświetlimy pierwsze zdjęcie w zestawie, dzięki. – Walter

Odpowiedz

3

Ponieważ jest to zestaw, jeśli chcesz, aby pierwszy element, będzie musiał przejść:

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

lub

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

Tak, przycisk/zdjęcie/viewImage/{anyPhotoId} wyświetla poprawnie zdjęcie. Właściwie myślę, że użyłem zestawu zamiast ArrayList. Czy to jest przyczyna problemu? Dzięki! – Walter

+0

@Walter - Ah tak. Poprawiłem moją odpowiedź. –

0

Domyślam się, trzeba ustawić typ zawartość strumień odpowiedzi. Coś jak:

response.ContentType = "image/jpeg" 

To może, ale nie musi być przed strumienia do strumienia odpowiedzi (nie mogę sobie wyobrazić, że to ważne). Właśnie umieściłbym to przed linią outputStream w powyższym kodzie.

+0

Przetestowałem to i wydaje się, że nie wymaga to ustawienia typu. Tks. – Walter

2

teraz, tak naprawdę uważam, że przechowywanie zdjęcia jako binarnego bloba w bazie danych nie jest najlepszym rozwiązaniem - choć możesz mieć powody, dla których trzeba to zrobić w ten sposób.

zamiast tego zamiast zapisywania nazwy zdjęcia (i/lub ścieżki)? Jeśli prawdopodobne jest występowanie konfliktów nazw, użyj nazwy sumy kontrolnej md5 zdjęcia. Wtedy zdjęcie staje się statycznym zasobem, prostym plikiem, zamiast bardziej skomplikowanym i wolniejszym żądaniem MVC.

+0

To może być opcja. Będę musiał zbadać to dalej. Dzięki! – Walter

+1

Co z zabezpieczeniem tego obrazu? Jeśli korzystasz z bezpośredniego adresu URL do pliku, tracisz możliwość (lub utrudnia to) zabezpieczenie obrazu dla określonych użytkowników/ról. – billjamesdev

+0

@bill: myślę, że to zależy od wymagań. Bezpieczeństwo będzie kosztować, a moja metoda jest nieco trudniejsza do zabezpieczenia (nie jest to niemożliwe, ale najprawdopodobniej jest łatwiejsza dzięki innym sugestiom, jeśli bezpieczeństwo jest ważne). – Chii

4

Jeśli masz adres URL obrazu, po prostu trzeba się upewnić, że zwróci odpowiednią Anser w kontrolerze:

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

id: 'profileInstance.photos.get (1) .ID powinny be id: profileInstance.photos.get (1) .id. bez limitu

1

Ja również uczę się gryzienia, szukając takiego przykładu. Sekret GSP mi nie pomógł. Postanowiłem zastępując apostrofów wokół profileInstance.photos.get (1) .ID

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

z cudzysłowach:

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

Teraz grails postanawia ekspresję wokół cudzysłowach. W przeciwnym razie bierze to jako ciąg.

Powiązane problemy