Как я могу получить и изображения на дисплее от базы данных на странице JSP?
Давайте пошагово посмотрим, что должно произойти:
. src
. src
должен указывать на действительный http://
URL, а не на путь к файловой системе локального диска file://
, так как это никогда не будет работать, если сервер и клиент работают на физически разных машинах. http://example.com/context/images/foo.png
), либо в качестве параметра запроса (например, http://example.com/context/images?id=1
). /images/*
, чтобы вы могли просто выполнить некоторый Java-код на определенных URL. byte[]
или InputStream
из БД, JDBC API предлагает ResultSet#getBytes()
и ResultSet#getBinaryStream()
для этого, а JPA API предлагает @Lob
для этого. байт[]
или InputStream
в OutputStream
ответа обычным Java IO способом. Content-Type
ответа также должен быть установлен. Вы можете получить правильный тип через ServletContext#getMimeType()
на основе расширения файла изображения, которое вы можете расширить и/или переопределить через
в web.xml
. На этом все. Это почти само пишет код. Начнем с HTML (в 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">
При необходимости вы можете также динамически установить src
с EL во время итерации с помощью JSTL:
<c:forEach items="${imagenames}" var="imagename">
<img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>
Затем определите/создайте сервлет, который слушает GET-запросы по шаблону URL /images/*
, в примере ниже для этого используется обычный JDBC:
@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);
}
}
}
Вот и все. Если вы беспокоитесь о HEAD, кэшировании заголовков и правильном ответе на эти запросы, используйте этот абстрактный шаблон для сервлета статических ресурсов.
Я предлагаю вам решить это как две проблемы. Есть несколько вопросов и ответов по обоим.
Как загрузить большой двоичный объект из MySQL
См., Например, Получить изображение, сохраненное как blob
Как отображать изображение динамически
См., Например, Динамическое отображение эскиза