When developing JAX-RS applications, most of the time, you return JSON to the client. However, there are times you need to return file download. For example, your client may require that when an user access a certain URL, the application must prompt a save file dialog.
If you have trouble with this requirement, look no further. I’m going to show you exactly how to return file download in JAX-RS application.
How to return file download
Let’s consider the following rest enpoint:
@GET @Path("file") @Produces(MediaType.TEXT_PLAIN) public String download() { return "directly to browser"; }
If you access the URL from the browser, I’m sure you can guess the result. It’s the text “directly to browser” just like this:
Now, what if you want instead of print the content to the browser, when an user visit the URL, a file is downloaded instead?
Consider the following code:
@GET @Path("file") @Produces(MediaType.TEXT_PLAIN) public Response download() { return Response.ok("directly to browser") .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;") .build(); }
If you visit the browser right now following the same URL as above, a file is downloaded instead.
You may wonder why the name of the file is file.txt? The reason is quite simple: Since I didn’t specify the file name (I’ll show you how later) and from the annotation, I set @Produce to TEXT_PLAIN, so JAX-RS was smart enough to get the path name and the content type to create the file name.
Let’s change the path to something else and change @Produce to XML.
@GET @Path("file-other") @Produces(MediaType.APPLICATION_XML) public Response download() { return Response.ok("directly to browser") .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;") .build(); }
Sure enough, the file name is now:
Let’s say now your client is very happy with the progress so far. However, she wants the name of the file to be something else and she doesn’t want to change the URL. What can you do?
Specify the download file’s name
If you need to set name for the downloaded file, simply set it in the header like so:
@GET @Path("file") @Produces(MediaType.APPLICATION_XML) public Response download() { return Response.ok("directly to browser") .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=great_file.xml") .build(); }
Now, if I visit the URL, I’ll get a file named great_file.xml
Conclusion
Returning file download is a common requirement in web projects. As you can see, by adding Content-Disposition header and set it to attachment, you can make a request return a file download instead of printing out text to the browser. You can also set name for the download file, if you like by specifying filename field.
I build softwares that solve problems. I also love writing/documenting things I learn/want to learn.