1

我正在尝试将我的应用程序中的图像作为 java.awt.BufferedImage 对象提供。当我尝试执行 GET 时,结果如下:

  • Accept:image/jpeg 渲染一张有效图片
  • Accept:*/* 返回 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 是“图像/JPEG”。据我了解,*/* 的接受标头永远不会生成 HTTP 406,根据此页面,它告诉我们调用者不接受该类型的内容。

这是一个问题,因为大多数浏览器的接受标头中都有“*/*”,除非用户对接受标头进行硬编码,否则将无法查看此图像。

我在这里错过了什么吗?

提前致谢。

4

1 回答 1

2

消息转换器对 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);
    }
}

然后在你的 spring 配置中使用它而不是普通的 BufferedImageHttpMessageConverter 。

选项 2:创建一个应用于您的图像请求的过滤器或拦截器,并以Accept标题看起来像image/jpeg而不是*/*. 这将“欺骗”认为客户端接受 jpeg 并触发 BufferedImageHttpMessageConverter。

于 2012-02-24T12:28:03.150 回答