2010-05-17 5 views
5

J'ai une base de données avec quelques images. Quelqu'un pourrait-il m'expliquer comment je pourrais charger une image dans une page JSF?Comment charger une image à partir d'une base de données dans une page JSF à l'aide de beans gérés?

J'ai déjà un bean géré qui convertit un objet Image en un flux de contenu. Ce flux est appelé depuis la page dans une balise <h:graphicImage>, mais lorsque je vérifie le code source de la page, il n'y a pas de src où l'image pourrait être chargée.

Répondre

12

Le JSF <h:graphicImage> est affiché en tant qu'élément HTML <img>. Son attribut src doit pointer vers une URL et non vers le contenu binaire. Vous devez donc stocker l'URL (ou au moins un identificateur comme paramètre de requête ou pathinfo) dans le bean JSF et créer une servlet séparée pour diffuser l'image de la base de données vers la réponse HTTP.

utiliser dans votre page JSF:

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

En supposant que bean.getImageId() rendements 123, ce se rendus en HTML:

<img src="images/123"> 

Créer une classe Servlet qui est mis en correspondance dans web.xml sur un url-pattern de /images/* et implémenter sa méthode doGet() comme suit .:

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) {} 
} 

Dans le ImageDAO#find(), vous pouvez utiliser ResultSet#getBinaryStream() à l'image en tant que InputStream à partir de la base de données. Un exemple étendu peut être trouvé dans this article.

+0

L'Entité d'Image à laquelle vous faites référence dans le code ci-dessus doit également contenir les attributs 'height' et 'width' non? – thejartender

+0

@thejartender: c'est gratuit à votre choix :) Il n'est cependant qu'inutile dans ce contexte. Vous préférez l'utiliser du côté de la vue (JSP/Facelets/etc) en imprimant les éléments «» nécessaires. – BalusC

+0

Pour quiconque trébucher sur ceci: Je soulignerais l'importance de ne pas utiliser l'identificateur simple pour récupérer l'image sauf si vous voulez qu'il soit totalement facile d'itérer (et télécharger) toutes les images de votre base de données. Au lieu de cela, utilisez la combinaison hashed de l'ID et du nom de fichier comme suggéré dans l'article BalusC publié. – mabi

Questions connexes