tags:

views:

362

answers:

1

I have a database with some images. Could anyone explain me how I could load an image in a JSF page?

I already have a managed bean that converts an Image object into a streamcontent. This streamcontent is called from the page in a tag <h:graphicImage>, but when I check the source code of the page, there's no src where the image could be loaded.

+1  A: 

The JSF <h:graphicImage> get rendered as a HTML <img> element. Its src attribute should point to an URL, not to the binary contents. So you should store the URL (or at least some identifier as request parameter or pathinfo) in the JSF bean and create a separate servlet to stream the image from the DB to the HTTP response.

Use this in your JSF page:

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

Assuming that bean.getImageId() returns 123, this get rendered in HTML as:

<img src="images/123">

Create a Servlet class which is mapped in web.xml on an url-pattern of /images/* and implement its doGet() method as follows.:

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

In the ImageDAO#find() you can use ResultSet#getBinaryStream() to the image as an InputStream from the database.

An extended example can be found in this article.

BalusC