java 如何在 Spring 应用程序的响应中正确返回图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15704342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to properly return an image in the response in Spring app?
提问by kumade
I 'm using Spring 3.0.1.RELEASE for my webapp (and i have no way for upgrading it) and i'm trying to render some images from database on web-page.
我正在为我的 web 应用程序使用 Spring 3.0.1.RELEASE(并且我无法升级它)并且我正在尝试从网页上的数据库呈现一些图像。
I have following simple Spring configs:
我有以下简单的 Spring 配置:
spring-application.xml:
弹簧应用程序.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>
spring-mvc.xml:
spring-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>
I have following controller:
我有以下控制器:
@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;
}
}
And finally, I have simple jsp-page:
最后,我有简单的 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"/>" />
If I open this page - I can see this image without any problems.
如果我打开此页面 - 我可以毫无问题地看到此图像。
But if I copy image "src" attribute and paste it in browser's address bar (Firefox 19.0.2) - then browser offers me to save carPhoto.html, instead of just render the image. Should I perform some additional setup?
但是,如果我复制图像“src”属性并将其粘贴到浏览器的地址栏(Firefox 19.0.2)中,那么浏览器会让我保存 carPhoto.html,而不仅仅是渲染图像。我应该执行一些额外的设置吗?
回答by Ralph
The problem is, that you have to specify the mime type (and if your image is larger you will need to specify its length too).
问题是,您必须指定 mime 类型(如果您的图像较大,您也需要指定其长度)。
An other solution () is to return a Spring ResponseEntity
or HttpEntity
(HttpEntity is enough if you always return http status code 200, ResponseEntity (a subclass of HttpEntity) is for example needed if you want to return other http status codes, like not found).
另一种解决方案 () 是返回一个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);
}
}
回答by CodeChimp
There are several ways. Easiest is to use @ResponseBody with a byte[] as your return type, set your Content-Type and such, the write the bytes to the output stream using the HttpServletResponse.
有几种方法。最简单的方法是使用带有 byte[] 的 @ResponseBody 作为返回类型,设置 Content-Type 等,然后使用 HttpServletResponse 将字节写入输出流。
A more elegant solution (IMO) would be to return a ModelAndView, then set the View on that to a custom view that sets the proper headers (Content-Type and such) and writes out the bytes to the HttpServletResponse's output stream.
一个更优雅的解决方案 (IMO) 是返回一个 ModelAndView,然后将其上的 View 设置为一个自定义视图,该视图设置正确的标头(Content-Type 等)并将字节写出到 HttpServletResponse 的输出流。