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)?
Spring @Controller annotation is also a specialization of @Component annotation. The @Controller annotation indicates that a particular class serves the role of a controller.
Interface StreamingResponseBody A controller method return value type for asynchronous request processing where the application can write directly to the response OutputStream without holding up the Servlet container thread.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With