Ответ 1
Для обеспечения максимальной производительности и эффективности не размещайте весь контент в byte[]
. Каждый byte
питается, да, один байт из памяти Java. Представьте себе 100 одновременных пользователей, которые запрашивают 10 изображений из каждых 100 КБ, которые уже потеряли 100 МБ памяти Java.
Получите изображение как InputStream
из БД с помощью ResultSet#getBinaryStream()
, оберните его в BufferedInputStream
и напишите его в OutputStream
ответа, завернутого в BufferedOutputStream
, через небольшой буфер byte[]
.
Предполагая, что вы выбираете изображения по ключу базы данных в качестве идентификатора, используйте это в своем HTML:
<img src="images/123">
Создайте класс Servlet
, который отображается в web.xml
на url-pattern
из /images/*
и реализует его метод doGet()
следующим образом.:
Long imageId = Long.valueOf(request.getPathInfo().substring(1)); // 123
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", String.valueOf(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];
for (int length = 0; (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) {}
}
В ImageDAO#find()
вы можете использовать ResultSet#getBinaryStream()
, чтобы получить изображение как InputStream
из базы данных.