2010-05-17 15 views
5

Ho un database con alcune immagini. Qualcuno potrebbe spiegarmi come caricare un'immagine in una pagina JSF?Come caricare un'immagine da un DB all'interno di una pagina JSF usando i bean gestiti?

Ho già un bean gestito che converte un oggetto Immagine in uno streamcontent. Questo streamcontent viene chiamato dalla pagina in un tag <h:graphicImage>, ma quando controllo il codice sorgente della pagina, non è disponibile lo src in cui è possibile caricare l'immagine.

risposta

12

Il JSF <h:graphicImage> viene visualizzato come elemento HTML <img>. L'attributo src deve puntare a un URL, non al contenuto binario. Pertanto, è necessario memorizzare l'URL (o almeno un identificatore come parametro di richiesta o pathinfo) nel bean JSF e creare un servlet separato per lo streaming dell'immagine dal DB alla risposta HTTP.

Usare questa nella tua pagina JSF:

<h:graphicImage value="images/#{bean.imageId}"> 

Supponendo che bean.getImageId() rendimenti 123, questo vengono resi in HTML come:

<img src="images/123"> 

creare una classe Servlet che viene mappato in web.xml su un url-pattern di /images/* e implementare il suo metodo doGet() come segue .:

Long imageId = Long.valueOf(request.getPathInfo().substring(1)); // 123 (PS: don't forget to handle any exceptions). 
Image image = imageDAO.find(imageId); // Get Image from DB. 
// Image class is just a Javabean with the following properties: 
// private String filename; 
// private Long length; 
// private InputStream content; 

response.setHeader("Content-Type", getServletContext().getMimeType(image.getFilename())); 
response.setHeader("Content-Length", image.getLength()); 
response.setHeader("Content-Disposition", "inline; filename=\"" + image.getFilename() + "\""); 

BufferedInputStream input = null; 
BufferedOutputStream output = null; 

try { 
    input = new BufferedInputStream(image.getContent()); 
    output = new BufferedOutputStream(response.getOutputStream()); 
    byte[] buffer = new byte[8192]; 
    int length; 
    while ((length = input.read(buffer)) > 0) { 
     output.write(buffer, 0, length); 
    } 
} finally { 
    if (output != null) try { output.close(); } catch (IOException logOrIgnore) {} 
    if (input != null) try { input.close(); } catch (IOException logOrIgnore) {} 
} 

Nel ImageDAO#find() è possibile utilizzare ResultSet#getBinaryStream() nell'immagine come InputStream dal database.

Un esempio esteso può essere trovato in this article.

+0

L'entità immagine a cui si fa riferimento nel codice sopra deve anche contenere attributi "altezza" e "larghezza" no? – thejartender

+0

@thejartender: è gratuito per la tua scelta :) È comunque inutile in questo contesto. Preferiresti usarlo dal lato della vista (JSP/Facelets/etc) mentre stampi gli elementi '' necessari. – BalusC

+0

Per chiunque inciampi su questo: sottolineerei l'importanza di NON usare l'id semplice per recuperare l'immagine a meno che tu non voglia che sia completamente semplice iterare (e scaricare) tutte le immagini dal tuo database. Utilizzare invece la combinazione hash di id e nomefile come suggerito nell'articolo BalusC pubblicato. – mabi

Problemi correlati