In Spring MVC application, to download a resource such as a file to the browser, you need to do the following in your controller.
- Use the
void
return type for your request-handling method and addHttpServletResponse
as an argument to the method. - Set the response’s content type to the file’s content type. If you do not know what the content type is or want the browser to always display the
Save As
dialog, set it toAPPLICATION/OCTET-STREAM
(NOT case sensitive). - Add an HTTP response header named Content-Disposition and give it the value attachment; filename=fileName, where
fileName
is the default file name that should appear in the File Download dialog box.
1. Sping MVC File Download Controller
Let’s look at an example implementation for file download controller.
@Controller @RequestMapping("/download") public class FileDownloadController { @RequestMapping("/pdf/{fileName:.+}") public void downloadPDFResource( HttpServletRequest request, HttpServletResponse response, @PathVariable("fileName") String fileName) { //If user is not authorized - he should be thrown out from here itself //Authorized user will download the file String dataDirectory = request.getServletContext().getRealPath("/WEB-INF/downloads/pdf/"); Path file = Paths.get(dataDirectory, fileName); if (Files.exists(file)) { response.setContentType("application/pdf"); response.addHeader("Content-Disposition", "attachment; filename="+fileName); try { Files.copy(file, response.getOutputStream()); response.getOutputStream().flush(); } catch (IOException ex) { ex.printStackTrace(); } } } }
Now if you hit the application URL : http://localhost:8080/springmvcexample/download/pdf/sample.pdf
, you will be able to get the Save As dialog box in your browser like below:

The file is placed inside folder “/WEB-INF/downloads/pdf”. You are free to change the path – make sure you change the controller code as well.

2. Prevent Cross-Referencing of File Downloads
Many times, other websites may cross reference your files in their websites as direct links. You may not want to allow it. To disallow all download requests, coming from other domains, you can check if the referer header contains your domain name.
Our modified FileDownloadController
will send files to the browser, only if the referer header is not null. This will prevent the images from being downloaded directly by typing their URLs in the browser or request coming from other domains.
@Controller @RequestMapping("/download") public class FileDownloadController { @RequestMapping("/pdf/{fileName:.+}") public void downloadPDFResource( HttpServletRequest request, HttpServletResponse response, @PathVariable("fileName") String fileName, @RequestHeader String referer) { //Check the renderer if(referer != null && !referer.isEmpty()) { //do nothing //or send error } //If user is not authorized - he should be thrown out from here itself //Authorized user will download the file String dataDirectory = request.getServletContext().getRealPath("/WEB-INF/downloads/pdf/"); Path file = Paths.get(dataDirectory, fileName); if (Files.exists(file)) { response.setContentType("application/pdf"); response.addHeader("Content-Disposition", "attachment; filename="+fileName); try { Files.copy(file, response.getOutputStream()); response.getOutputStream().flush(); } catch (IOException ex) { ex.printStackTrace(); } } } }
Now if you try to hit the URL from browser directly, you will get this error:
java.lang.IllegalStateException: Missing header 'referer' of type [java.lang.String] at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.raiseMissingHeaderException(HandlerMethodInvoker.java:797) at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestHeader(HandlerMethodInvoker.java:566) at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:355) at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:172) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:446)
Drop me your questions in comments section.
Happy Learning !!
Jessica
Hi, how can I download multiple files without getting save as dialogs for each and saving them automatically to a folder
Lokesh Gupta
I never seen anything like this until you are using some download manager.
sabrina
the file is downloaded, but it is missing the text of the content, all blank
soekarno
sir, how to prevent pdf file being downloaded in certain field? from {filename = } that has different id from other documents.
thankyou
SRAVAN
how to display files like images, pdf, zip from the local folder in JSP using spring MVC
using while loop to display all files in folder
archie reducto
how to display pdf file using java netbeans from database? do have a sample code?
Shafqat Shafi
Thanks a lot for sharing your knowledge.
kanika agarwal
Good example. I changed the content type to ‘csv’ and it worked for me.
Naresh
can please tell me that how to download a file in another folder like
my applications in D:/Project/
my file saved in Another Directory like E:/Upload/Docs/Naresh.doc how to download
can u please tell me
B Chaitanya
Of the same. I need a folder to convert into zip format. Can you post that ASAP please.
Avinash tiwari
Hi i have to do same but i need to send request header with download url for user authentication. so m not getting how ill add request header with it?
Siddhartha Murari
thanks.. good example. Thank yOU very much