Spring MVC: How to return image in @ResponseBody?

2019-01-02 19:13发布

I'm getting image data (as byte[]) from DB. How to return this image in @ResponseBody ?

EDIT

I did it without @ResponseBody using HttpServletResponse as method parameter:

@RequestMapping("/photo1")
public void photo(HttpServletResponse response) throws IOException {
    response.setContentType("image/jpeg");
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    IOUtils.copy(in, response.getOutputStream());
}

Using @ResponseBody with registered org.springframework.http.converter.ByteArrayHttpMessageConverter converter as @Sid said doesn't work for me :(.

@ResponseBody
@RequestMapping("/photo2")
public byte[] testphoto() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    return IOUtils.toByteArray(in);
}

标签: spring-mvc
14条回答
谁念西风独自凉
2楼-- · 2019-01-02 19:52

In your application context declare a AnnotationMethodHandlerAdapter and 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> 

also in the handler method set appropriate content type for your response.

查看更多
大哥的爱人
3楼-- · 2019-01-02 19:53

if you are using Spring version of 3.1 or newer you can specify "produces" in @RequestMapping annotation. Example below works for me out of box. No need of register converter or anything else if you have web mvc enabled (@EnableWebMvc).

@ResponseBody
@RequestMapping(value = "/photo2", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
public byte[] testphoto() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    return IOUtils.toByteArray(in);
}
查看更多
高级女魔头
4楼-- · 2019-01-02 19:59

Non of the answers worked for me, so I've managed to do it like that:

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);

Setting Content-Disposition header I was able to download the file with the @ResponseBody annotation on my method.

查看更多
骚的不知所云
5楼-- · 2019-01-02 20:02

In addition to registering a ByteArrayHttpMessageConverter, you may want to use a ResponseEntity instead of @ResponseBody. The following code works for me :

@RequestMapping("/photo2")
public ResponseEntity<byte[]> testphoto() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");

    final HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.IMAGE_PNG);

    return new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
}
查看更多
不流泪的眼
6楼-- · 2019-01-02 20:02

In spring 4 it's very easy you don't need to make any changes in beans. Only mark your return type to @ResponseBody.

Example:-

@RequestMapping(value = "/image/{id}")
    public @ResponseBody
    byte[] showImage(@PathVariable Integer id) {
                 byte[] b;
        /* Do your logic and return 
               */
        return b;
    }
查看更多
萌妹纸的霸气范
7楼-- · 2019-01-02 20:05

With Spring 4.1 and above, you can return pretty much anything (such as pictures, pdfs, documents, jars, zips, etc) quite simply without any extra dependencies. For example, the following could be a method to return a user's profile picture from 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()));
}

The things to note:

  • ResponseEntity with InputStreamResource as a return type

  • ResponseEntity builder style creation

With this method you dont have to worry about autowiring in the HttpServletResponse, throwing an IOException or copying stream data around.

查看更多
登录 后发表回答