Let’s say you want to create a REST API which returns a Microsoft Word Document.
When a client calls that API the document gets automatically downloaded to their system.
How do you do it?
Here is the algorithm:
STEP1: Create a REST API which returns a byte array
STEP2: Configure the return type of the REST API as “application/octet-stream”
STEP3: Convert the file into a byte array
STEP4: Set headers for Content Type and Content Disposition
STEP5: Return the response along with the byte array and headers
STEP6: Test application
STEP1: Create a REST API
Here is a sample REST API:
@GetMapping(value = "/msworddocument")
public ResponseEntity<byte[]> download() {
// return response here
}
The return type is a response entity with byte array as the response body
STEP2: Configure the return type of the REST API as “application/octet-stream”
Use “produces” attribute of your REST Mapping annotation (I have used @GetMapping ) to specify the return type as “application/octet-stream”:
@GetMapping(value = "/msworddocument", produces = { "application/octet-stream" })
public ResponseEntity<byte[]> download() {
//return
}
STEP3: Convert the file into a byte array
Load the file you want your user to download and convert it into a byte array:
@GetMapping(value = "/msworddocument", produces = { "application/octet-stream" })
public ResponseEntity<byte[]> download() {
try {
File file = ResourceUtils.getFile("classpath:test.docx");
byte[] contents =
Files.readAllBytes(Paths.get(file.getAbsolutePath()));
//return response here
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
I created a word document called test.docx and placed it in the resources folder.
STEP4: Set headers for Content Type and Content Disposition
This is the major change to be done to allow users to download your word document.
The Content Type header should be set to “application/octet-stream”
The Content Disposition header should be set to “attachment” along with the file name (the name in which the file gets downloaded to their local machine)
@GetMapping(value = "/msworddocument", produces = { "application/octet-stream" })
public ResponseEntity<byte[]> download() {
try {
File file = ResourceUtils.getFile("classpath:test.docx");
byte[] contents = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDisposition(ContentDisposition.attachment().filename("yourfile.docx").build());
//return here
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
STEP5: Return the response along with the byte array and headers
Return the byte array and the headers using ResponseEntity object:
@GetMapping(value = "/msworddocument", produces = { "application/octet-stream" })
public ResponseEntity<byte[]> download() {
try {
File file = ResourceUtils.getFile("classpath:test.docx");
byte[] contents = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDisposition(ContentDisposition.attachment().filename("yourfile.docx").build());
return new ResponseEntity<>(contents, headers, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
STEP6: Test application
I ran the application and loaded the URL in my browser.
The file got downloaded using the name mentioned under “Content Disposition” header:

That’s it.
Code can be found here:
Leave a Reply