Spring controller: Content-Type for StreamingResponseBody

Viewed 11264

In search for the least amount of code to serve a BufferedImage (painted in a service-class) from a spring-mvc Controller, I came up with the following:

@GetMapping(value = "/image", produces = "image/png")
public StreamingResponseBody image() {
    BufferedImage canvas = service.createImage();
    return outputStream -> ImageIO.write(canvas, "png", outputStream);
}

So far, so good - using the image in HTML via <img src="/image"> works fine.

However, spring does not send any Content-Type header at all. Together with serving X-Content-Type-Options: nosniff in the response, this leads to garbage in the browser window when the image URL is opened directly.

How do I provide a content-type header in the most spring-friendly way (i.e. not using HttpServletResponse directly)?

1 Answers

You can wrap it in a ResponseEntity<...>, this allows you to easily modify all the parameters in the response through the response builder:

@GetMapping(value = "/image", produces = "image/png")
public ResponseEntity<StreamingResponseBody> image() {
    BufferedImage canvas = service.createImage();

    StreamingResponseBody stream = outputStream ->
            ImageIO.write(canvas, "png", outputStream);

    return ResponseEntity.ok()
        .contentType(MediaType.IMAGE_PNG)
        .body(stream);
}
Related