How can I retrieve and display images from a database in a JSP page?
You can display image by keeping image name in request scope and fetch it by its name JSTL. String imageName = "test. jpg"; request.
Build the list of filenames to display. List imageUrlList = new ArrayList(); File imageDir = new File("/myapp/images"); for(File imageFile : imageDir. listFiles()){ String imageFileName = imageFile. getName(); // add this images name to the list we are building up imageUrlList.
Let's see in steps what should happen:
<img>
element.src
attribute.src
attribute needs to point to a valid http://
URL and thus not a local disk file system path file://
as that would never work when the server and client run at physically different machines.http://example.com/context/images/foo.png
) or as request parameter (e.g. http://example.com/context/images?id=1
)./images/*
, so that you can just execute some Java code on specific URL's.byte[]
or InputStream
from the DB, the JDBC API offers the ResultSet#getBytes()
and ResultSet#getBinaryStream()
for this, and JPA API offers @Lob
for this.byte[]
or InputStream
to the OutputStream
of the response the usual Java IO way.Content-Type
response header needs to be set as well. You can obtain the right one via ServletContext#getMimeType()
based on image file extension which you can extend and/or override via <mime-mapping>
in web.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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With