Сбой согласования содержимого Spring MVC при обслуживании BufferedImage - PullRequest
1 голос
/ 24 февраля 2012

Я пытаюсь использовать изображение в моем приложении как объект java.awt.BufferedImage. Когда я пытаюсь выполнить GET, вот результаты:

  • Принять: изображение / JPEG отображает действительное изображение
  • Принять: * / * возвращает HTTP 406

Вот соответствующая часть моего servlet-context.xml:

    <beans:bean id="messageAdapter"
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <beans:property name="order" value="1" />
    <beans:property name="messageConverters">
        <beans:array>
            <beans:bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
        </beans:array>
    </beans:property>

</beans:bean>

А вот мой контроллер:

    @RequestMapping(value = "photo/{photoId:[0-9]+}", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public BufferedImage getPhoto(
        @PathVariable long photoId) {
        return photoService.getPhoto(photoId);
    }

MediaType.IMAGE_JPEG_VALUE - это "image / jpeg". Насколько я понимаю, заголовок accept * / * никогда не будет генерировать HTTP 406, который согласно этой странице говорит нам, что вызывающая сторона не принимает содержимое этого типа.

Это проблема, потому что большинство браузеров имеют "* / *" в своих заголовках принятия и не смогут просматривать это изображение, если пользователь не жестко закодировал заголовок принятия.

Я что-то здесь упускаю?

Заранее спасибо.

1 Ответ

2 голосов
/ 24 февраля 2012

Конвертеры сообщений требовательны к заголовку Accept, и они должны быть такими, поскольку они применяются ко всем обработчикам, помеченным @ResponseBody.

. Есть несколько способов обойти это:

Вариант 1: Расширьте BufferedImageHttpMessageConverter, чтобы обрабатывать также */*, ПРИМЕЧАНИЕ: это может иметь непредвиденные последствия, если позже вы добавите другие конвертеры сообщений, так как неожиданно обработчики, для которых вы хотите создать JSON, вместо этого начнут создавать изображения.

public class ExtendedBufferedImageHttpMessageConverter extends BufferedImageHttpMessageConverter {

    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
    if (mediaType.equals(MediaType.ALL)) {
        return super.canWrite(clazz, MediaType.IMAGE_JPEG);
    } else {
        return super.canWrite(clazz, mediaType);
    }
}

Затем используйте это вместо обычного BufferedImageHttpMessageConverter в вашей весенней конфигурации.

Вариант 2: создайте фильтр или перехватчик, который применяется к вашим запросам изображений, и оберните запрос таким образомзаголовок Accept выглядит как image/jpeg вместо */*.Это «обманет» мысль о том, что клиент принимает jpeg и запускает BufferedImageHttpMessageConverter.

...