Download an Image or a File with Spring MVC

1. Overview

Serving static files to the client can be done in a variety of ways, and
using a Spring Controller isn’t necessarily the best available option.

However, sometimes the controller route is necessary – and that’s what
we’re going to be focused on in this quick article____.

2. Using @ResponseBody

The first straightforward solution is to use the @ResponseBody
annotation on a controller method to indicate that the object returned
by the method should be marshalled directly to the HTTP response body:

@GetMapping("/get-text")
public @ResponseBody String getText() {
    return "Hello world";
}

Thus, this method will just return the string Hello world instead of
returning a view whose name is Hello world, like a more typical MVC
application.

With @ResponseBody we can return pretty much any media type, as long
as we have a corresponding HTTP Message converter that can handle and
marshall that to the output stream.

3. Using produces for Returning Images

Returning byte arrays allows us to return almost anything – such as
images or files:

@GetMapping(value = "/image")
public @ResponseBody byte[] getImage() throws IOException {
    InputStream in = getClass()
      .getResourceAsStream("/com/baeldung/produceimage/image.jpg");
    return IOUtils.toByteArray(in);
}

Here, we’re not defining that the returned byte array is an image.
Therefore, the client won’t be able to handle this as an image – and
more than likely the browser will simply e display the actual bytes of
the image.

To define that the returned byte array corresponds to an image, we can
set the produces attribute of the @GetMapping annotation to precise
the MIME type of the returned object:

@GetMapping(
  value = "/get-image-with-media-type",
  produces = MediaType.IMAGE_JPEG_VALUE
)
public @ResponseBody byte[] getImageWithMediaType() throws IOException {
    InputStream in = getClass()
      .getResourceAsStream("/com/baeldung/produceimage/image.jpg");
    return IOUtils.toByteArray(in);
}

Here produces is set to MediaType.IMAGE_JPEG_VALUE to indicate that
the returned object must be handled as a JPEG image.

And now, the browser is going to recognize and properly display the
response body as an image.

4. Using produces for Returning Raw Data

The parameter produces can be set to a lot of different values (the
complete list can be found
here)
depending on the type of object we want to return.

Therefore, if we want to return a raw file, we can simply use
APPLICATION_OCTET_STREAM_VALUE:

@GetMapping(
  value = "/get-file",
  produces = MediaType.APPLICATION_OCTET_STREAM_VALUE
)
public @ResponseBody byte[] getFile() throws IOException {
    InputStream in = getClass()
      .getResourceAsStream("/com/baeldung/produceimage/data.txt");
    return IOUtils.toByteArray(in);
}

5. Conclusion

In this quick article, we had a look at a simple problem – returning
images or files from a Spring Controller.

And, as always, the example code can be found
over on
Github
.

Leave a Reply

Your email address will not be published.