Для лучшей производительности и эффективности не помещайте весь контент в 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
из базы данных.