提供 BufferedImage 时 Spring MVC 内容协商失败

发布于 2025-01-08 05:32:52 字数 1282 浏览 1 评论 0原文

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

  • Accept:image/jpeg renders a valid picture
  • Accept:*/* returns an 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”。据我了解, */* 的接受标头永远不会生成 HTTP 406,根据 this page 告诉我们调用者不接受该类型的内容。

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

我在这里错过了什么吗?

提前致谢。

I'm trying to serve an image in my application as a java.awt.BufferedImage object. When I attempt to perform a GET, here are the results:

  • Accept:image/jpeg renders a valid picture
  • Accept:*/* returns an HTTP 406

Here is the relevant part of my 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>

And here is my Controller:

    @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 is "image/jpeg". It is my understanding that an accept header of */* would never generate a HTTP 406, which according to this page tells us that the caller doesn't accept content of that type.

This is an issue because most browsers have "*/*" in their accept headers, and would not be able to view this image unless the user hard-coded the accept header.

Am I missing something here?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

杯别 2025-01-15 05:32:52

消息转换器对 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。

Message converters are picky about the Accept header, and they have to be since they are applied to all handlers annotated with @ResponseBody.

A couple of ways you can get around this:

Option 1: Extend the BufferedImageHttpMessageConverter to handle */* as well, NOTE: this can have unintended consequences if you add other message-converters later on as all of a sudden, handlers you want to produce JSON starts producing images instead.

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);
    }
}

Then use this instead of the normal BufferedImageHttpMessageConverter in your spring config.

Option 2: Create a filter or interceptor that is applied to your image requests and wrap the request in such a way the Accept header looks like image/jpeg instead of */*. This will "trick" spring into thinking that the client accepts jpeg and trigger the BufferedImageHttpMessageConverter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文