Подтвердить что ты не робот

Запись ответа на сервлет с лучшей производительностью

Я пишу образ для ответа сервлета с лучшей производительностью. Любые советы, практика, опыт?

4b9b3361

Ответ 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 из базы данных.

Ответ 2

вы можете использовать байт типа массива для изображения из сервлета, если он есть в базе данных типа Blob.

byte[] image;

или есть еще один способ, но он немного сложный. когда вы вызываете ваш сервлет, поэтому перед этим вам нужно определить, является ли вызов для изображения, или это обычный вызов. если это обычный вызов, тогда u может продолжить вызов сервлета, но если это вызов для изображения, тогда не вызывайте сервлет, но вы можете хранить ссылки на изображения в каком-либо физическом месте на компьютере и извлекать их.

Но этот метод не будет работать, если у вас есть изображения в БД, скорее у вас могут быть относительные пути в БД, а затем вы можете получить изображение с этого пути.

Ответ 3

Если изображения статичны, имейте в виду, что самый быстрый ответ - это тот, который обрабатывается до того, как он доберется до вас.

Вы можете встать Apache httpd перед вашим сервером Tomcat. Вы можете использовать другие варианты кеширования пограничных серверов. Есть много трюков вдоль этих линий.

Конечно, это предполагает, что ваше приложение написано там, где URL-адрес эффективно сопоставляется с одним изображением способом, который легко кэшируется. Если вашему приложению не хватает этого, преимущества достаточно велики, чтобы рассмотреть возможность реструктуризации.