Java 如何在Spring应用程序的响应中正确返回图像?

Java 如何在Spring应用程序的响应中正确返回图像?,java,image,spring,httpresponse,Java,Image,Spring,Httpresponse,我正在使用Spring3.0.1.RELEASE来开发我的webapp(我没有办法升级它),我正在尝试在网页上呈现数据库中的一些图像 我有以下简单的Spring配置: spring-application.xml: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org

我正在使用Spring3.0.1.RELEASE来开发我的webapp(我没有办法升级它),我正在尝试在网页上呈现数据库中的一些图像

我有以下简单的Spring配置:

spring-application.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    <task:annotation-driven />

    <context:annotation-config />

    <context:spring-configured />

    <context:component-scan base-package="com.me" />

    <bean id="hibernateSessionFactory" class="com.me.dbaccess.HibernateSessionFactory">
        <constructor-arg ref="sessionFactory"/>
    </bean>
</beans>
最后,我有一个简单的jsp页面:

<%@page contentType="text/html; charset=utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<img id="photoImage" src="<c:url value="/carPhoto.html?photoType=1&photoId=22556793"/>" />

" />
如果我打开这个页面-我可以看到这个图像没有任何问题

但是,如果我复制图像“src”属性并将其粘贴到浏览器的地址栏(Firefox19.0.2)中,那么浏览器会让我保存carPhoto.html,而不仅仅是渲染图像。
我应该执行一些额外的设置吗?

有几种方法。最简单的方法是使用带有字节[]的@ResponseBody作为返回类型,设置内容类型,然后使用HttpServletResponse将字节写入输出流

更优雅的解决方案(IMO)是返回ModelAndView,然后将其上的视图设置为自定义视图,该视图设置适当的头(内容类型等),并将字节写入HttpServletResponse的输出流



问题是,您必须指定mime类型(如果图像较大,则还需要指定其长度)

另一个解决方案()是返回or(如果总是返回http状态代码200,则HttpEntity就足够了,例如,如果希望返回其他http状态代码,如not found,则需要ResponseEntity(HttpEntity的子类)

@控制器
公共级光电控制器{
@请求映射(“/carPhoto.html”)
@应答器
公共HttpEntity getCarPhoto(
@RequestParam(UrlParameters.PHOTO_ID)整数photoId,
@RequestParam(UrlParameters.PHOTO_TYPE)字符串(photoType){
byte[]image=按照片Id和类型从数据库中提取的图像字节数组;
HttpHeaders=新的HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG);//或它的任何类型
headers.setContentLength(image.length);
返回新的HttpEntity(图像、标题);
}
}

+1用于分析缺少的mime类型,但您的“更优雅的解决方案”是spring 2.x解决方案。spring 3.x有一些更优雅的方式(IMO)(请参阅我的答案)感谢您的快速回答。Upss。无法编辑我以前的评论。感谢您的快速回答。我已尝试设置内容类型,但没有成功(可能是我做错了):`public byte[]getCarPhoto(@RequestParam Integer photoId,@RequestParam String photoType,HttpServletResponse){byte[]image=db中的图像;response.setContentType(“image/jpg”);response.setContentLength(image.length);return image;}‘至于‘更优雅的解决方案’——对于这样一个简单的任务来说,它不是太复杂了吗?:)返回类型中缺少@ResponseBody。您可以将它放在byte[]或整个方法之前。@CodeChimp我刚才在注释中省略了它,但实际上我已经有了它(就像在原始代码示例中一样)在完成整个方法之前。感谢您的回复。我很想使用您的解决方案,但我无法使用我的Spring版本(3.0.1.RELEASE).HttpEntity和ResponseEntity来自3.1.x,对吗?
HttpEntity
ResponseEntity
是在3.0.2中引入的,但无论如何我不能使用它,因为我不能升级到3.0.2。3.0.1中有类似的东西吗?我不知道。但我强烈建议花时间升级,而不是复制新版本的功能对old once(超过3年!)唉,这不是我决定继续使用这个Spring版本(或升级到新版本)。我只是在使用我拥有的,不能用它做任何事情:)无论如何,谢谢你和CodeChimp的回答和你的关注。这个问题解决了吗,如果是,请分享如何解决,我面临着同样的问题
@Controller
public class PhotoController {
    @RequestMapping("/carPhoto.html")
    @ResponseBody
    public byte[] getCarPhoto(
            @RequestParam(UrlParameters.PHOTO_ID) Integer photoId,
            @RequestParam(UrlParameters.PHOTO_TYPE) String photoType) {
        //return image's bytes array from db by photo Id and Type;
    }
}
<%@page contentType="text/html; charset=utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<img id="photoImage" src="<c:url value="/carPhoto.html?photoType=1&photoId=22556793"/>" />
@Controller
public class PhotoController {
    @RequestMapping("/carPhoto.html")
    @ResponseBody
    public HttpEntity<byte[]> getCarPhoto(
            @RequestParam(UrlParameters.PHOTO_ID) Integer photoId,
            @RequestParam(UrlParameters.PHOTO_TYPE) String photoType) {


        byte[] image = image's bytes array from db by photo Id and Type;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_JPEG); //or what ever type it is
        headers.setContentLength(image.length);
        return new HttpEntity<byte[]>(image, headers);
    }
}