Anda di halaman 1dari 2

jsf - How to populate h:graphicImage value with image content from database? https://stackoverflow.com/questions/15074465/how-to-populate-hgraphicimage-value-with-imag...

jsf - How to populate h:graphicImage value with image content from database?

There's a major misunderstanding here. JSF is basically a HTML code producer. In HTML, images are not inlined in the HTML output.
Instead, they are supposed to be represented by <img> elements with a (relative) URL in the src attribute which the browser has to download
individually during parsing the obtained HTML output. Look at the generated HTML output, the JSF <h:graphicImage> component generates a
HTML <img> element which must have a src attribute pointing to a valid URL.

The <h:graphicImage value> must represent a valid URL. If you've however stored images in the DB instead of in the public webcontent, then
you should basiclly be creating a standalone servlet which reads the individual image from the DB based on some unique request parameter or
URL path and writes it to the response body.

So assuming that you render the image URL as follows from now on,

<h:graphicImage value="/userProfileImageServlet?id=#{userProfile.id}" />

then the following kickoff example (trivial checks like nullchecks etc omitted) of the servlet should do:

@WebServlet("/userProfileImageServlet")
public class UserProfileImageServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Long userProfileId = Long.valueOf(request.getParameter("id"));

try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT image, imageFileName, LENGTH(image) AS imageContentLength FROM use
) {
statement.setLong(1, userProfileId);

try (ResultSet resultSet = statement.executeQuery()) {


if (resultSet.next()) {
response.setContentType(getServletContext().getMimeType(resultSet.getString("imageFileName")));
response.setContentLength(resultSet.getInt("imageContentLength"));
response.setHeader("Content-Disposition", "inline;filename=\"" + resultSet.getString("imageFileName") + "\"");

try (
ReadableByteChannel input = Channels.newChannel(resultSet.getBinaryStream("image"));
WritableByteChannel output = Channels.newChannel(externalContext.getResponseOutputStream());
) {
for (ByteBuffer buffer = ByteBuffer.allocateDirect(10240); input.read(buffer) != -1; buffer.clear()) {
output.write((ByteBuffer) buffer.flip());
}

1 of 3 1/23/19, 8:33 PM
jsf - How to populate h:graphicImage value with image content from database? https://stackoverflow.com/questions/15074465/how-to-populate-hgraphicimage-value-with-imag...

}
}
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
} catch (SQLException e) {
throw new ServletException("Something failed at SQL/DB level.", e);
}
}

If you happen to use JSF utility library OmniFaces on a JSF 2.2 + CDI environment, then you can instead use its <o:graphicImage> which
could be used more intuitively.

<o:graphicImage value="#{userProfileImageBean.getBytes(userProfile.id)}" />

@Named
@ApplicationScoped
public class UserProfileImageBean {

public byte[] getBytes(Long userProfileId) {


try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT image FROM userProfile WHERE id=?");
) {
statement.setLong(1, userProfileId);

try (ResultSet resultSet = statement.executeQuery()) {


if (resultSet.next()) {
return resultSet.getBytes("image");
}
} else {
return null;
}
} catch (SQLException e) {
throw new FacesException("Something failed at SQL/DB level.", e);
}
}

It also transparently supports date URI scheme by just setting dataURI="true":

<o:graphicImage value="#{userProfileImageBean.getBytes(userProfile.id)}" dataURI="true" />

See also:

2 of 3 1/23/19, 8:33 PM

Anda mungkin juga menyukai