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

kum*_*ade 5 java spring image httpresponse

我正在使用Spring 3.0.1.RELEASE为我的webapp(我无法升级它),我正在尝试从网页上的数据库渲染一些图像.

我有以下简单的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>
Run Code Online (Sandbox Code Playgroud)

弹簧mvc.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <mvc:annotation-driven/>

    <bean id="tilesViewResolver" class="com.me.util.TilesExposingBeansViewResolver">
        <property name="viewClass" value="com.me.util.TilesExposingBeansView"/>
        <property name="exposeContextBeansAsAttributes" value="true"/>
    </bean>

    <bean id="tilesConfigurer"
          class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/config/tiles-defs.xml</value>
            </list>
        </property>
    </bean>
</beans>
Run Code Online (Sandbox Code Playgroud)

我有以下控制器:

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,我有简单的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"/>" />
Run Code Online (Sandbox Code Playgroud)

如果我打开这个页面 - 我可以毫无问题地看到这个图像.

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

Ral*_*lph 6

问题是,你必须指定mime类型(如果你的图像更大,你也需要指定它的长度).

另一个解决方案()是返回一个SpringResponseEntity或者HttpEntity(如果你总是返回http状态代码200,则HttpEntity就足够了,如果你想返回其他http状态代码,例如找不到,则需要ResponseEntity(HttpEntity的一个子类)).

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Cod*_*imp 2

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

一个更优雅的解决方案(IMO)是返回一个 ModelAndView,然后将其上的视图设置为自定义视图,该视图设置正确的标头(Content-Type 等)并将字节写出到 HttpServletResponse 的输出流。