Я реализую REST-API с JavaEE-Techniques, к которому будут доступны мобильные приложения и ответы с некоторыми JSON-Data в ответ на их запросы. Пока все замечательно, пока мы не заметили, что вопрос очень необычный. Сначала я подумал, что это «сложный» запрос базы данных, который работает так долго, но после некоторой отладки он указал, что доступ к thumbnailpicture из полученных данных методом ImageIO.read (URL) является причиной запроса до принять поэтому длинный.ImageIO.read (URL) берет навсегда загрузку изображения
Через запрос базы данных Я получаю URL-адрес, указывающий на данные изображения (миниатюр), которые я хочу получить. Прежде чем я создам JSON-Data объекта для отправки его клиенту, я собираюсь кодировать изображение как base64-String.
Мой код выглядит следующим образом (я знаю, что он не такой приятный на данный момент, но так, как я его до сих пор работаю, я знаю, что могу использовать блоки try-resource и, вероятно, должен преобразовать запись в срубы уровень отладки, и я собираюсь):
public class Base64Utility
{
public static String encodeBase64FromUrl(final URL pImageUrl, final ThumbnailPictureDbo pThumbnailPicture)
{
BufferedImage img = null;
String base64EncodedImageString = null;
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] imageBytes = null;
try
{
logger.info("Starting to convert the image!");
final Long start = System.currentTimeMillis();
// The Sucker!
img = ImageIO.read(pImageUrl);
final Long imageLoadTime = System.currentTimeMillis() - start;
logger.info("Loaded Image from url {} in: {}", pImageUrl, imageLoadTime);
final Long start2 = System.currentTimeMillis();
ImageIO.write(img, "png", bos);
imageBytes = bos.toByteArray();
final Long imageWriteTime = System.currentTimeMillis() - start2;
logger.info("Wrote Image in: {}", imageWriteTime);
bos.close();
final Long start3 = System.currentTimeMillis();
// What to return when img == null?!
base64EncodedImageString = imageBytes != null ? Base64.getEncoder()
.encodeToString(imageBytes) : "";
final Long imageEncodeTime= System.currentTimeMillis() - start3;
logger.info("Encoded Image in: {}", imageEncodeTime);
pThumbnailPicture.setBase64EncodedImage(base64EncodedImageString);
logger.info("Finished converting the image!");
logger.info("Took total time: " + (System.currentTimeMillis() - start));
return base64EncodedImageString;
}
catch (final IOException e)
{
e.printStackTrace();
}
return base64EncodedImageString;
}
The изображений размещаются на же машине расположена база данных и код работает на. Таким образом, URL-парам содержит имя хоста, но также может быть доступен через «localhost» или в виде файла (но он хранится с именем хоста в базе данных. Для удобства я его не конвертирую, найдя также очень удобный ImageIO .read (URL).) Таким образом, сеть также не должна быть узким местом.
Очень странное поведение: ImageIO занимает 10-60 секунд, обращаясь к изображению по первому вызову. После этого (несколько данных результата в одном и том же запросе-клиенте) требуется всего 100 миллисекунд.
По новому новому запросу он ведет себя одинаково (первый вызов занимает ненормальный длинный и на следующих очень короткий). Это выход из некоторых журналов (в течение одного запроса клиента!):
Starting to convert the image!
Loaded Image from url <URL>/Logo-KF-transparent-1500-1024x992.png in: 21810
Wrote Image in: 973
Encoded Image in: 3
Finished converting the image!
Took total time: 22787
Starting to convert the image!
Loaded Image from url <URL>/IMG_1026_905.jpg in: 157
Wrote Image in: 440
Encoded Image in: 7
Finished converting the image!
Took total time: 605
Starting to convert the image!
Loaded Image from url <URL>/WorkshopS2_KaffeeFabrik_1200x800-500x300.jpg in: 23
Wrote Image in: 101
Encoded Image in: 2
Finished converting the image!
Took total time: 127
Starting to convert the image!
Loaded Image from url <URL>/kaffeezumabnehmen.jpg in: 226
Wrote Image in: 98
Encoded Image in: 4
Finished converting the image!
Took total time: 329
Starting to convert the image!
Loaded Image from url <URL>/kaffee_apa.jpg in: 12
Wrote Image in: 60
Encoded Image in: 2
Finished converting the image!
Took total time: 75
Того самое поведение не зависит от в изображениях ни на формате Изображения в, это всегда первый доступ/которая занимает так много времени! У кого-нибудь есть идея или решение? Мне тоже хорошо с другим подходом к чтению/загрузке изображений, это была только моя первая попытка и первый результат некоторых исследований. Возможно, для этого существует совершенно другой и лучший подход.
Я звоню утилиту из фасоли RequestScoped-КДИ следующим образом:
@RequestScoped
public class LocationPersistenceServiceImpl implements LocationPersistenceService
{
// Some other attributes and methods...
@Override
public List<LocationData> findLocations(final QueryParams[] pQueryParams)
{
final QueryBuilder<LocationDbo> qb = new QueryBuilder<>(pQueryParams, emf, LocationDbo.class);
final List<LocationDbo> locationDboQueryResults = qb.getResultList();
for (LocationDbo retrievedLocDbo : locationDboQueryResults)
{
retrievedLocDbo = enhanceRetrievedLocationDboMetaInformation(retrievedLocDbo);
}
return dboToData.convert(locationDboQueryResults);
}
private LocationDbo enhanceRetrievedLocationDboMetaInformation(LocationDbo pRetrievedLocDbo)
{
final List<PostMetaInformationDbo> postMetaInfos = pPs.retrievePostMetaInfomationsById(pRetrievedLocDbo.getPostId());
pRetrievedLocDbo = addRetrievedLocationMetaInfosFromLocationPost(pRetrievedLocDbo, postMetaInfos);
return pRetrievedLocDbo;
}
private LocationDbo addRetrievedLocationMetaInfosFromLocationPost(final LocationDbo pLocDbo, final List<PostMetaInformationDbo> pPostMeta)
{
for (final PostMetaInformationDbo p : pPostMeta)
{
// Some code...
}
if ((pLocDbo.getThumbnailPicture() != null) && (!StringUtils.isBlank(pLocDbo.getThumbnailPicture()
.getGuid())))
{
Base64Utility.encodeBase64FromUrl(pLocDbo.getThumbnailPicture()
.getGuid(), pLocDbo.getThumbnailPicture());
}
return pLocDbo;
}
}
Еще одна моя идея будет аннотировать класс Base64Utility как Stateless боба и ввести его в класс обслуживания. Возможно, это может улучшить некоторые процедуры кэширования/подключения или поддерживать параллельное выполнение/потоки или подобное (еще не пробовал).
Возможно, у кого-то были подобные проблемы или у вас возникли очевидные нарушения при работе с ImageIO и он может поделиться своим знанием.
Спасибо и с наилучшими пожеланиями!
P.S.: весь код работает на сервере приложений Wildlfy (8.2.Final и на Java 8). Таким образом, запуск некоторых потоков вручную при работе с ImageIO (как показывают некоторые сообщения в моем исследовании) не должно быть отличной идеей.
Вы пытались загрузить URL-адрес изображения с помощью веб-браузера или другого инструмента (завиток, wget и т. Д.), Чтобы узнать, загружаются ли они быстрее? В любом случае последующие чтения быстрее, потому что URL-адрес кэшируется. Кроме того, ByteArrayOutputStream.toByteArray() * never * возвращает null. – VGR
Да, конечно. Но я, наверное, обманул. Открытие URL-адреса с помощью firefox, казалось, сработало мгновенно -> Img, скорее всего, был кэширован. Доступ к URL-адресу на закрытой вкладке занял у меня 27 сек. Редактировать: Также wget на удаленной машине (на которой размещены изображения) занял 10 - 20 секунд. – Sebsen36
Голосование, чтобы закрыть этот вопрос, поскольку реальная проблема, похоже, заключается в генерации изображений на сервере и/или сетевом вводе-выводе, а не напрямую связана с ImageIO.read. – haraldK