How to retrieve and display images from a database in a JSP page?
How can I retrieve and display images from a database in a JSP page?
Let's see in steps what should happen:
- JSP is basically a view technology which is supposed to generate HTML output.
- To display an image in HTML, you need the HTML
<img>
element. - To let it locate an image, you need to specify its
src
attribute. - The
src
attribute needs to point to a validhttp://
URL and thus not a local disk file system pathfile://
as that would never work when the server and client run at physically different machines. - The image URL needs to have the image identifier in either the request path (e.g.
http://example.com/context/images/foo.png
) or as request parameter (e.g.http://example.com/context/images?id=1
). - In JSP/Servlet world, you can let a Servlet listen on a certain URL pattern like
/images/*
, so that you can just execute some Java code on specific URL's. - Images are binary data and are to be obtained as either a
byte[]
orInputStream
from the DB, the JDBC API offers theResultSet#getBytes()
andResultSet#getBinaryStream()
for this, and JPA API offers@Lob
for this. - In the Servlet you can just write this
byte[]
orInputStream
to theOutputStream
of the response the usual Java IO way. - The client side needs to be instructed that the data should be handled as an image, thus at least the
Content-Type
response header needs to be set as well. You can obtain the right one viaServletContext#getMimeType()
based on image file extension which you can extend and/or override via<mime-mapping>
inweb.xml
.
That should be it. It almost writes code itself. Let's start with HTML (in JSP):
<img src="${pageContext.request.contextPath}/images/foo.png">
<img src="${pageContext.request.contextPath}/images/bar.png">
<img src="${pageContext.request.contextPath}/images/baz.png">
You can if necessary also dynamically set src
with EL while iterating using JSTL:
<c:forEach items="${imagenames}" var="imagename">
<img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>
Then define/create a servlet which listens on GET requests on URL pattern of /images/*
, the below example uses plain vanilla JDBC for the job:
@WebServlet("/images/*")
public class ImageServlet extends HttpServlet {
// content=blob, name=varchar(255) UNIQUE.
private static final String SQL_FIND = "SELECT content FROM Image WHERE name = ?";
@Resource(name="jdbc/yourDB") // For Tomcat, define as <Resource> in context.xml and declare as <resource-ref> in web.xml.
private DataSource dataSource;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String imageName = request.getPathInfo().substring(1); // Returns "foo.png".
try (Connection connection = dataSource.getConnection(); PreparedStatement statement = connection.prepareStatement(SQL_FIND)) {
statement.setString(1, imageName);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
byte[] content = resultSet.getBytes("content");
response.setContentType(getServletContext().getMimeType(imageName));
response.setContentLength(content.length);
response.getOutputStream().write(content);
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
}
}
} catch (SQLException e) {
throw new ServletException("Something failed at SQL/DB level.", e);
}
}
}
That's it. In case you worry about HEAD and caching headers and properly responding on those requests, use this abstract template for static resource servlet.
See also:
- How should I connect to JDBC database / datasource in a servlet based application?
- How to upload an image and save it in database?
- Simplest way to serve static data from outside the application server in a Java web application
I suggest you address that as two problems. There are several questions and answer related to both.
-
How to load blob from MySQL
See for instance Retrieve image stored as blob
-
How to display image dynamically
See for instance Show thumbnail dynamically