Returning Image/Media Data with Spring MVC – 用Spring MVC返回图像/媒体数据

最后修改: 2016年 5月 17日


1. Overview


In this tutorial, we’ll illustrate how to return images and other media using the Spring MVC framework.

在本教程中,我们将说明如何使用Spring MVC框架返回图片和其他媒体。

We will discuss several approaches, starting from directly manipulating HttpServletResponse than moving to approaches that benefit from Message Conversion, Content Negotiation and Spring’s Resource abstraction. We’ll take a closer look on each of them and discuss their advantages and disadvantages.


2. Using the HttpServletResponse


The most basic approach of the image download is to directly work against a response object and mimic a pure Servlet implementation, and its demonstrated using the following snippet:


@RequestMapping(value = "/image-manual-response", method = RequestMethod.GET)
public void getImageAsByteArray(HttpServletResponse response) throws IOException {
    InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
    IOUtils.copy(in, response.getOutputStream());

Issuing the following request will render the image in a browser:



The implementation is fairly straightforward and simple owing to IOUtils from the package. However, the disadvantage of the approach is that it’s not robust against the potential changes. The mime type is hard-coded and the change of the conversion logic or externalizing the image location requires changes to the code.


The following section discusses a more flexible approach.


3. Using the HttpMessageConverter


The previous section discussed a basic approach that does not take advantage of the Message Conversion and Content Negotiation features of the Spring MVC Framework. To bootstrap these features we need to:

上一节讨论了一种基本的方法,它没有利用Spring MVC框架的消息转换内容协商功能。为了引导这些功能,我们需要。

  • Annotate the controller method with the @ResponseBody annotation
  • Register an appropriate message converter based on the return type of the controller method (ByteArrayHttpMessageConverter for example needed for correct conversion of bytes array to an image file)

3.1. Configuration


For showcasing the configuration of the converters, we will use the built-in ByteArrayHttpMessageConverter that converts a message whenever a method returns the byte[] type.


The ByteArrayHttpMessageConverter is registered by default, but the configuration is analogous for any other built-in or custom converter.


Applying the message converter bean requires registering an appropriate MessageConverter bean inside Spring MVC context and setting up media types that it should handle. You can define it via XML, using <mvc:message-converters> tag.

应用消息转换器Bean需要在Spring MVC上下文中注册一个适当的MessageConverterBean,并设置它应该处理的媒体类型。你可以通过XML定义它,使用<mvc:message-converters> tag。

This tag should be defined inside <mvc:annotation-driven> tag, like in the following example:


        <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
            <property name="supportedMediaTypes">

Aforementioned configuration part will register ByteArrayHttpMessageConverter for image/jpeg and image/png response content types. If <mvc:message-converters> tag is not present in the mvc configuration, then the default set of converters will be registered.


Also, you can register the message converter using Java configuration:


public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
    ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
    return arrayHttpMessageConverter;

private List<MediaType> getSupportedMediaTypes() {
    List<MediaType> list = new ArrayList<MediaType>();
    return list;

3.2. Implementation


Now we can implement our method that will handle requests for media. As it was mentioned above, you need to mark your controller method with the @ResponseBody annotation and use byte[] as the returning type:


@RequestMapping(value = "/image-byte-array", method = RequestMethod.GET)
public @ResponseBody byte[] getImageAsByteArray() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
    return IOUtils.toByteArray(in);

To test the method, issue the following request in your browser:



On the advantage side, the method knows nothing about the HttpServletResponse, the conversion process is highly configurable, ranging from using the available converters to specifying a custom one. The content type of the response does not have to be hard-coded rather it will be negotiated based on the request path suffix .jpg.


The disadvantage of this approach is that you need to explicitly implement the logic for retrieving the image from a data source (local file, external storage, etc.) and you don’t have control over the headers or the status code of the response.


4. Using the ResponseEntity Class


You can return an image as byte[] wrapped in the Response Entity. Spring MVC ResponseEntity enables control not only over the body of the HTTP Response but also the header and the response status code. Following this approach, you need to define the return type of the method as ResponseEntity<byte[]> and create returning ResponseEntity object in the method body.

你可以将图片作为byte[]包裹在Response Entity中返回。Spring MVC的ResponseEntity不仅可以控制HTTP响应的主体,还可以控制头和响应状态代码。按照这种方法,你需要将方法的返回类型定义为ResponseEntity<byte[]>,并在方法主体中创建返回ResponseEntity对象。

@RequestMapping(value = "/image-response-entity", method = RequestMethod.GET)
public ResponseEntity<byte[]> getImageAsResponseEntity() {
    HttpHeaders headers = new HttpHeaders();
    InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
    byte[] media = IOUtils.toByteArray(in);
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK);
    return responseEntity;

Using the ResponseEntity allows you to configure a response code for a given request.


Explicitly setting the response code is especially useful in the face of an exceptional event e.g. if the image was not found (FileNotFoundException) or is corrupted (IOException). In these cases, all that is needed is setting the response code e.g. new ResponseEntity<>(null, headers, HttpStatus.NOT_FOUND), in an adequate catch block.

明确设置响应代码在面对特殊事件时特别有用,例如,如果没有找到图像(FileNotFoundException)或被破坏(IOException)。在这些情况下,所需要的是设置响应代码,例如new ResponseEntity<>(null, headers, HttpStatus.NOT_FOUND),在一个适当的catch块中。

In addition, if you need to set some specific headers in your response, this approach is more straightforward than setting headers by means of HttpServletResponse object that is accepted by the method as a parameter. It makes the method signature clear and focused.


5. Returning Image Using the Resource Class

5.使用Resource Class返回图像

Finally, you can return an image in the form of the Resource object.


The Resource interface is an interface for abstracting access to low-level resources. It is introduced in Spring as a more capable replacement for the standard class. It allows easy access to different types of resources (local files, remote files, classpath resources) without the need to write a code that explicitly retrieves them.


To use this approach the return type of the method should be set to Resource and you need to annotate the method with the @ResponseBody annotation.


5.1. Implementation


@RequestMapping(value = "/image-resource", method = RequestMethod.GET)
public Resource getImageAsResource() {
   return new ServletContextResource(servletContext, "/WEB-INF/images/image-example.jpg");

or, if we want more control over the response headers:


@RequestMapping(value = "/image-resource", method = RequestMethod.GET)
public ResponseEntity<Resource> getImageAsResource() {
    HttpHeaders headers = new HttpHeaders();
    Resource resource = 
      new ServletContextResource(servletContext, "/WEB-INF/images/image-example.jpg");
    return new ResponseEntity<>(resource, headers, HttpStatus.OK);

Using this approach, you treat images as resources that can be loaded using the ResourceLoader interface implementation. In such case, you abstract from the exact location of your image and ResourceLoader decides from where it is loaded.


It provides a common approach to control the location of images using the configuration, and eliminate the need for writing file loading code.


6. Conclusion


Among the aforementioned approaches, we started from the basic approach, then using the approach that benefits from the message conversion feature of the framework. We also discussed how to get the set the response code and response headers without handing the response object directly.


Finally, we added flexibility from the image locations point of view, because where to retrieve an image from, is defined in the configuration that is easier to change on the fly.


Download an Image or a File with Spring explains how to achieve the same thing using Spring Boot.

Download an Image or a File with Spring解释了如何使用Spring Boot实现同样的事情。

The sample code following the tutorial is available at GitHub.