I am working on a Spring Boot backend application.
I have to retrieve a jpg image from a BLOB field on my database and return it to the frontend.
Searching online I have found this tutorial about how the controller should return a file to display: http://www.leveluplunch.com/java/tutorials/032-return-file-from-spring-rest-webservice/
As you can see in the previous tutorial it do something like this:
@RequestMapping(value = "/", method = RequestMethod.GET, produces = "application/pdf")
public ResponseEntity<InputStreamResource> downloadPDFFile()
throws IOException {
ClassPathResource pdfFile = new ClassPathResource("pdf-sample.pdf");
return ResponseEntity
.ok()
.contentLength(pdfFile.contentLength())
.contentType(
MediaType.parseMediaType("application/octet-stream"))
.body(new InputStreamResource(pdfFile.getInputStream()));
}
So, it is returning a InputStreamResource object wrapped into a ResponseEntity.
In the past I do it using a standard Java array of bytes. Reading the documentation I found that InputStreamResource is a specific Spring object: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/io/InputStreamResource.html
So, from what I have understand, I have the standard Java InputStream type that is an abstract class that is is the superclass of all classes representing an input stream of bytes (so something like as I done in the past). Then the InputStreamResource (used in the previous tutorial) is a specific Resource implementation of the InputStream.
Reading the documentation Resource is a Spring interface used to describe any type of resources (so images, files, etcetc).
So my doubt is this InputStreamResource the right choice to return a JPEG files to my front-end application as byte array?
I have this doubt because in the official documentation I read:
Should only be used if no other specific Resource implementation is applicable. In particular, prefer ByteArrayResource or any of the file-based Resource implementations where possible.
Is it a good solution?
In general it is a good idea to stream your results back to the client. The simple reason for that is that images and attachments are getting larger. When you return a byte array, you have to have all of those bytes in memory at once. That introduces you to an accidental denial of service incident if your image or attachment you are sending is too large to be in memory at once.
General Guidelines:
ClassPathResource
in your response entity.FileSystemResource
to return a file on diskInputStreamResource
if there isn't already another resource type. Example is returning blob contentExample of how to use the InputStreamResource
:
return new InputStreamResource(blob.getPayload().openStream()) {
@Override
public long contentLength() {
return blob.getMetadata().getContentMetadata().getContentLength();
}
};
I would caution against the lazy thinking of returning a byte array. It should only be considered if your response sizes are about 1MB or less.
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