服务BufferedImage时,Spring MVC内容协商失败

时间:2012-02-23 23:54:01

标签: java spring-mvc content-type content-negotiation

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

  • 接受:image / 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,根据this page,它告诉我们调用者不接受该类型的内容。

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

我在这里错过了什么吗?

提前致谢。

1 个答案:

答案 0 :(得分: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 config中使用它而不是普通的BufferedImageHttpMessageConverter。

选项2:创建应用于图像请求的过滤器或拦截器,并以Accept标头image/jpeg标头而不是*/*的方式包装请求。这将“欺骗”春天认为客户端接受jpeg并触发BufferedImageHttpMessageConverter。