2010-05-17 9 views
5

Tengo una base de datos con algunas imágenes. ¿Alguien podría explicarme cómo puedo cargar una imagen en una página JSF?¿Cómo cargo una imagen desde una base de datos dentro de una página JSF utilizando beans administrados?

Ya tengo un bean administrado que convierte un objeto de imagen en un contenido de secuencia. Este streamcontent se llama desde la página en una etiqueta <h:graphicImage>, pero cuando verifico el código fuente de la página, no hay src donde la imagen podría cargarse.

Respuesta

12

El JSF <h:graphicImage> se representa como un elemento HTML <img>. Su atributo src debe apuntar a una URL, no a los contenidos binarios. Por lo tanto, debe almacenar la URL (o al menos algún identificador como parámetro de solicitud o información de ruta) en el bean JSF y crear un servlet separado para transmitir la imagen desde el DB a la respuesta HTTP.

utilizar esto en su página JSF:

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

Suponiendo que bean.getImageId() vuelve 123, esto consiguen prestan en HTML como:

<img src="images/123"> 

Crear una clase Servlet que está mapeado en web.xml en una url-pattern de /images/* e implementar su método doGet() de la siguiente manera .:

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

En el ImageDAO#find() puede usar ResultSet#getBinaryStream() en la imagen como InputStream de la base de datos.

Un ejemplo extendido se puede encontrar en this article.

+0

La entidad de imagen a la que hace referencia en el código anterior también debe contener los atributos 'alto' y 'ancho' ¿no? – thejartender

+0

@thejartender: es gratis a su elección :) Sin embargo, es inútil en este contexto. Prefiere usarlo en el lado de la vista (JSP/Facelets/etc) mientras imprime los elementos necesarios ' '. – BalusC

+0

Para cualquier persona que tropiece con esto: destacaría la importancia de NO usar el ID simple para buscar la imagen a menos que desee que sea totalmente fácil de iterar (y descargar) todas las imágenes de su base de datos. En su lugar, use la combinación hash de id y filename como se sugiere en el artículo publicado por BalusC. – mabi

Cuestiones relacionadas