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
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
DownloadPDFController we will stub in the method in which we will want to map a request to.
Creating a Request Method
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.
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
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
Thanks for joining in today's level up, have a great day!