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.