Spring MVC:如何在@ResponseBody中返回图像?
我从数据库中获取图像数据(如byte[]
)。 如何在@ResponseBody
返回这个图片?
编辑
我没有使用@ResponseBody
使用HttpServletResponse
作为方法参数:
@RequestMapping("/photo1") public void photo(HttpServletResponse response) throws IOException { response.setContentType("image/jpeg"); InputStream in = servletContext.getResourceAsStream("http://img.dovov.comno_image.jpg"); IOUtils.copy(in, response.getOutputStream()); }
使用@ResponseBody
与注册org.springframework.http.converter.ByteArrayHttpMessageConverter
转换器@Sid说不适用于我:(。
@ResponseBody @RequestMapping("/photo2") public byte[] testphoto() throws IOException { InputStream in = servletContext.getResourceAsStream("http://img.dovov.comno_image.jpg"); return IOUtils.toByteArray(in); }
如果您使用的是3.1或更新版本的Spring版本,则可以在@RequestMapping
注释中指定“产生”。 下面的例子为我开箱即用。 如果您启用了web mvc( @EnableWebMvc
),则无需注册转换器或其他任何东西。
@ResponseBody @RequestMapping(value = "/photo2", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE) public byte[] testphoto() throws IOException { InputStream in = servletContext.getResourceAsStream("http://img.dovov.comno_image.jpg"); return IOUtils.toByteArray(in); }
使用Spring 4.1及以上版本,您可以非常简单地返回任何东西(如图片,pdf,文档,jar子,拉链等),而无需任何额外的依赖关系。 例如,以下可能是从MongoDB GridFS返回用户个人资料图片的方法:
@RequestMapping(value = "user/avatar/{userId}", method = RequestMethod.GET) @ResponseBody public ResponseEntity<InputStreamResource> downloadUserAvatarImage(@PathVariable Long userId) { GridFSDBFile gridFsFile = fileService.findUserAccountAvatarById(userId); return ResponseEntity.ok() .contentLength(gridFsFile.getLength()) .contentType(MediaType.parseMediaType(gridFsFile.getContentType())) .body(new InputStreamResource(gridFsFile.getInputStream())); }
要注意的是:
-
用InputStreamResource作为返回types的ResponseEntity
-
ResponseEntity构build器样式创build
有了这个方法,你不必担心HttpServletResponse中的自动assembly,抛出一个IOException或者复制stream数据。
除了注册ByteArrayHttpMessageConverter
,您可能还想使用ResponseEntity
而不是@ResponseBody
。 以下代码适用于我:
@RequestMapping("/photo2") public ResponseEntity<byte[]> testphoto() throws IOException { InputStream in = servletContext.getResourceAsStream("http://img.dovov.comno_image.jpg"); final HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.IMAGE_PNG); return new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED); }
通过使用Spring 3.1.x和3.2.x,这是你应该这样做的:
控制器方法:
@RequestMapping("/photo2") public @ResponseBody byte[] testphoto() throws IOException { InputStream in = servletContext.getResourceAsStream("http://img.dovov.comno_image.jpg"); return IOUtils.toByteArray(in); }
和servlet-context.xml文件中的mvc注释:
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>image/jpeg</value> <value>image/png</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
除了几个答案之外(Spring 4.1)。
如果您没有在WebMvcConfig中configuration任何消息转换器,那么在您的@ResponseBody中有ResponseEntity
可以@ResponseBody
工作。
如果你这样做,即你有一个MappingJackson2HttpMessageConverter
configuration(像我一样)使用ResponseEntity
返回一个org.springframework.http.converter.HttpMessageNotWritableException
。
在这种情况下唯一的工作解决scheme是在@ResponseBody
包装一个byte[]
,如下所示:
@RequestMapping(value = "/get/image/{id}", method=RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE) public @ResponseBody byte[] showImageOnId(@PathVariable("id") String id) { byte[] b = whatEverMethodUsedToObtainBytes(id); return b; }
在这种情况下,请记住在WebMvcConfig中正确configurationmessageconverters(并添加一个ByteArrayHttpMessageConverer
),如下所示:
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(mappingJackson2HttpMessageConverter()); converters.add(byteArrayHttpMessageConverter()); } @Bean public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(objectMapper); return converter; } @Bean public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() { ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter(); arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes()); return arrayHttpMessageConverter; } private List<MediaType> getSupportedMediaTypes() { List<MediaType> list = new ArrayList<MediaType>(); list.add(MediaType.IMAGE_JPEG); list.add(MediaType.IMAGE_PNG); list.add(MediaType.APPLICATION_OCTET_STREAM); return list; }
在您的应用程序上下文中声明一个AnnotationMethodHandlerAdapter和registerByteArrayHttpMessageConverter:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <util:list> <bean id="byteArrayMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> </util:list> </property> </bean>
也在处理程序方法中为你的响应设置适当的内容types。
@RequestMapping(value = "/get-image",method = RequestMethod.GET) public ResponseEntity<byte[]> getImage() throws IOException { RandomAccessFile f = new RandomAccessFile("/home/vivex/apache-tomcat-7.0.59/tmpFiles/1.jpg", "r"); byte[] b = new byte[(int)f.length()]; f.readFully(b); final HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.IMAGE_PNG); return new ResponseEntity<byte[]>(b, headers, HttpStatus.CREATED); }
为我工作。
我赞成这一个:
private ResourceLoader resourceLoader = new DefaultResourceLoader(); @ResponseBody @RequestMapping(value = "/{id}", produces = "image/bmp") public Resource texture(@PathVariable("id") String id) { return resourceLoader.getResource("classpath:images/" + id + ".bmp"); }
将媒体types更改为您拥有的任何图像格式。
这在春季4是适合我的。
@RequestMapping(value = "/image/{id}", method = RequestMethod.GET) public void findImage(@PathVariable("id") String id, HttpServletResponse resp){ final Foto anafoto = <find object> resp.reset(); resp.setContentType(MediaType.IMAGE_JPEG_VALUE); resp.setContentLength(anafoto.getImage().length); final BufferedInputStream in = new BufferedInputStream(new ByteArrayInputStream(anafoto.getImageInBytes())); try { FileCopyUtils.copy(in, resp.getOutputStream()); resp.flushBuffer(); } catch (final IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
没有答案为我工作,所以我设法做到这一点:
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("your content type here")); headers.set("Content-Disposition", "attachment; filename=fileName.jpg"); headers.setContentLength(fileContent.length); return new ResponseEntity<>(fileContent, headers, HttpStatus.OK);
设置Content-Disposition
头我可以用我的方法下载带有@ResponseBody
注解的文件。
这就是我用Spring Boot和Guava做的事情:
@RequestMapping(value = "/getimage", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE) public void getImage( HttpServletResponse response ) throws IOException { ByteStreams.copy( getClass().getResourceAsStream( "/preview-image.jpg" ), response.getOutputStream() ); }
在spring4,很容易,你不需要在豆做任何改变。 只将您的返回types标记为@ResponseBody。
例:-
@RequestMapping(value = "/image/{id}") public @ResponseBody byte[] showImage(@PathVariable Integer id) { byte[] b; /* Do your logic and return */ return b; }
- 使用Spring的@Autowired注解时,IntelliJ IDEA会显示错误
- 只从Spring MVC 3控制器返回string消息
- Spring MVC中ModelAndView的Model是什么?
- @GetMapping和@RequestMapping之间的区别(method = RequestMethod.GET)
- 如何使用<sec:authorize access =“hasRole('ROLES)”>检查多个angular色?
- Spring 3 Web MVC入门 – 设置一切
- 找不到具有URI的HTTP请求的映射…在名称为的DispatcherServlet中
- Struts2与Spring 3
- Web框架:与Spring MVC有什么不同?