It is easy serving a static asset from a spring web application but what if you needed to fetch a file from a database or a file system? In this episode find out how to return a file from a spring controller.
Detailed Video Notes
In this example we will show how to read a PDF from the classpath simulating a read from a database or a file system and downloading it from a RESTful web service. While we use a PDF you could substitute just about any file format such as gif, jpeg, tiff, png, zip, jars, wars, ear or any other binary format that you need to stream to your browser. More examples show how to make a get request for json and return xml from a spring rest service
Project set up
[0:16]
Visiting spring initializer website and selecting web project dependency we will create a spring boot skeleton project. Opening the project in eclipse we will copy a sample pdf named pdf-sample.pdf into the resource directory. Finally creating a @RestController
named DownloadPDFController
we will stub in the method in which we will want to map a request to.
Creating a Request Method
[0:17]
In the DownloadPDFController
we will create a default request mapping for the application. The return type will be a ResponseEntity
, an extension of HttpEntity
that adds a HttpStatus code, and will be of type InputStreamResource
. Next for demonstration purposes we fetch a file named pdf-sample.pdf from the classpath by using ClassPathResource
. This could be substituted by reading a file from a network drive or retrieving it from a database. Once we have hold of the file we can use ResponseEntityBuilder
introduced in Spring 4.1 setting the length, content type and the body of the response to be the file.
Let's go ahead and run our example and navigate to http://localhost:8080/ to view the pdf.
Prevent caching
[1:20]
Often times when you are returning document you may want to prevent caching so that the next time a request is made it returns the most current version. Luckily the ResoponseEnity
allows you to set the headers on the response. We will create HttpHeaders
object setting Cache-Control, Pragma and Expires properties. In the event where you want to prevent caching across your entire application you could set the response in either a Filter
or a HandlerInterceptor
.
ByteArrayHttpMessageConverter
Just in case you need it, you may need to register a custom message converter named ByteArrayHttpMessageConverter
. To do this, if you are using spring boot you can create a bean named "customConverters" creating ByteArrayHttpMessageConverter
and populating a HttpMessageConverters
object.
Thanks for joining in today's level up, have a great day!