浏览器显示jpeg的原始图像数据.我应该在回复中确定哪些标题?

Pet*_*háč 10 java browser servlets spring-mvc http-headers

我似乎遇到了一个有趣的问题,浏览器愉快地显示由我的Spring MVC Web应用程序生成的图像,只要我的控制器的URL设置为IMG标记的SRC,但在直接导航到URL时显示二进制数据.

我的Spring MVC Controller生成一些BufferedImage(缩略图),将其转换为byte[]并使用@ResponseBody控制器方法上的注释将其直接返回到响应主体.我已经注册了一个org.springframework.http.converter.ByteArrayHttpMessageConverter消息转换器,AnnotationMethodHandlerAdapter甚至将其supportedMediaTypes属性设置为image/jpeg,这实际上没有帮助,所以我在控制器方法中手动设置响应的Content-Type标头.

<img src="/images/thumbnail?id=1234" />
Run Code Online (Sandbox Code Playgroud)

工作正常并显示图像,但直接导航到图像的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)
Run Code Online (Sandbox Code Playgroud)

最后一句话:在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();
    }
}
Run Code Online (Sandbox Code Playgroud)

=== UPDATE === 我已经按照@BalusC的建议并将生成缩略图的网址更改为实际的.jpg文件.这有所不同,现在我可以"保存图像为",文件名不再只是"缩略图"而是".jpg",这是好的.但是,Chrome和FF(我还没有开始在IE上测试)在将URL加载到新的选项卡/窗口时显示原始JFIF数据.尽管如此,当用户在新选项卡中选择查看图像时,图像仅显示URL是否在IMG标记的SRC属性中(并且由于浏览器缓存)(但仅当用户不刷新选项卡时,刷新选项卡才会重新获取JPEG并在窗口中显示原始数据).

编辑 我刚刚在IE9中对此进行了测试,这是唯一可以按预期工作的浏览器.我可以直接导航到URL并不断刷新页面,我可以看到我的控制器被点击,JPEG被加载到浏览器窗口中.优秀.现在要弄清楚FF/CR处理我发送的JPEG的方式有什么问题.

其他信息 我正在使用Spring版本3.0.6.RELEASE从Jetty运行Web应用程序

编辑 我已经通过使用@ResponseBody而解决了我的问题BytArrayHttpMessageConverter- 我尝试在另一个线程中提出的解决方法在SO上 - 这就是直接将字节写入响应输出流:IOUtils.copy(imageInputStream, response.getOutputStream());这很简单并且有效,我仍然好奇什么是浏览器如何在<img>标签中加载响应但不直接在浏览器窗口中加载奇怪的问题.任何人都可以对此有所了解,我真的很想知道更多.我暂时没有回答这个问题.

小智 2

尝试将注释更新为:

@RequestMapping(value = "thumbnail", method = { RequestMethod.GET }, produces = {"image/jpeg"})    
@ResponseBody
Run Code Online (Sandbox Code Playgroud)

注意produces属性。

希望有帮助。