Браузер отображает необработанные данные изображения jpeg. Какие заголовки я должен обязательно иметь в ответе?

Кажется, я столкнулся с интересной проблемой, когда браузер успешно отображает изображение, сгенерированное моим веб-приложением Spring MVC, если URL-адрес моего контроллера установлен как SRC тега IMG , но отображает двоичные данные при переходе непосредственно к URL-адресу.

Мой Spring MVC Controller генерирует некоторый BufferedImage (эскиз), преобразует его в байт [] и возвращает его непосредственно в тело ответа с помощью @ResponseBody аннотация к методу контроллера. Я зарегистрировал org.springframework.http.converter.Конвертер сообщений ByteArrayHttpMessageConverter с помощью AnnotationMethodHandlerAdapter и даже установил для его свойства supportedMediaTypes значение image / jpeg , что на самом деле не помогло, поэтому я устанавливаю Заголовок Content-Type в ответе вручную в методе контроллера.

<img src="/images/thumbnail?id=1234" />

работает нормально и отображает изображение, однако переход непосредственно к SRC изображения (или щелчок правой кнопкой мыши и выбор «Просмотр изображения») приводит к отображению необработанных данных изображения.

Заголовки ответа, согласно Firebug, полученные от запроса на такой URL ( http: // localhost: 8888 / images / thumbnail? Id = F0snPkvwhtDbl8eutbuq ):

HTTP/1.1 200 OK
Expires: Wed, 21 Dec 2011 12:39:07 GMT
Cache-Control: max-age=2592000
Content-Type: image/jpeg
Content-Length: 6998
Server: Jetty(6.1.10)

Последнее слово: in Firebug, при нажатии на вкладку Response отображается изображение :-) Что я упускаю? Я думал, что браузер получает заголовки типа содержимого и длины содержимого, знает, что нужно ожидать изображения jpeg, получает необработанные данные для jpeg, а затем отображает jpeg на пустой вкладке браузера. Каким-то образом FF и Chrome отображают полученные необработанные данные изображения.

Код, который я использую:

@RequestMapping(value = "thumbnail", method = { RequestMethod.GET })
@ResponseBody
public byte[] getImageThumbnail(@RequestParam("id") String documentId, HttpServletResponse response) {
    try {
        Document document = documentService.getDocumentById(documentId);
        InputStream imageInputStream = new FileInputStream(document.getUri());
        response.setContentType("image/jpeg");

        BufferedImage img = ImageIO.read(imageInputStream);
        ResampleOp resampleOp = new ResampleOp(THUMBNAIL_DIMENSION);
        BufferedImage thumbnail = resampleOp.filter(img, null);
        return getDataFromBufferedImage(thumbnail);
    } catch (Throwable t) {
        return null; //return no data if document not found or whatever other issues are encountered
    }
}

private byte[] getDataFromBufferedImage(BufferedImage thumbnail) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {
        ImageIO.write(thumbnail, "jpg", baos);
        baos.flush();
        return baos.toByteArray();
    } finally {
        baos.close();
    }
}

=== UPDATE === Я последовал совету @BalusC и изменил URL-адрес, который создает миниатюру, чтобы она выглядела как настоящий файл .jpg. Это имело некоторую разницу в том, что теперь я могу «Сохранить изображение как», а имя файла больше не просто «эскиз», а «.jpg», что хорошо. Однако и Chrome, и FF (я даже не начал тестирование в IE) отображают необработанные данные JFIF при загрузке URL-адреса в новую вкладку / окно.Тем не менее, изображение отображается только в том случае, если URL-адрес находится в атрибуте SRC тега IMG и (благодаря кешированию браузера), когда пользователь выбирает Просмотр изображения на новой вкладке (но только если пользователь не обновляет вкладку, обновление вкладки будет повторно загружено JPEG и отобразить необработанные данные в окне).

РЕДАКТИРОВАТЬ Я только что протестировал это в IE9, и это единственный браузер, в котором он работает должным образом. Я могу напрямую перейти к URL-адресу и продолжать обновлять страницу, и я вижу, что мой контроллер поражен, а JPEG загружается в окно браузера. Превосходно. Теперь выясним, что не так с тем, как FF / CR обрабатывает отправляемый мной JPEG.

Дополнительная информация Я использую Spring версии 3.0.6.RELEASE Запуск веб-приложения с Jetty

РЕДАКТИРОВАТЬ Я решил свою проблему by , а не , используя @ResponseBody и BytArrayHttpMessageConverter - Я попробовал обходной путь, предложенный в другом потоке здесь, на SO - просто записать байты непосредственно в ответ stream: IOUtils.copy (imageInputStream, response.getOutputStream ()); Это просто и работает, мне все еще любопытно, в чем заключалась странная проблема с тем, как браузеры загружали ответ в < img> , но не непосредственно в окне браузера. Кто угодно может пролить свет на это, мне было бы очень интересно узнать больше. Я пока оставляю этот вопрос без ответа.

10
задан Peter Perháč 13 December 2011 в 09:52
поделиться