My problem is that I am getting the wrong sized file on the client side. Here is my @Controller ...
@RequestMapping(value = "/download/{id}", method = RequestMethod.GET)
public ResponseEntity<?> download(final HttpServletRequest request,
final HttpServletResponse response,
@PathVariable("id") final int id) throws IOException {
try {
// Pseudo-code for retrieving file from ID.
Path zippath = getZipFile(id);
if (!Files.exists(zippath)) {
throw new IOException("File not found.");
}
ResponseEntity<InputStreamResource> result;
return ResponseEntity.ok()
.contentLength(Files.size(zippath))
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new InputStreamResource(new FileInputStream(zippath.toFile())));
} catch (Exception ex) {
// ErrorInfo is another class, unimportant
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ErrorInfo(ex));
}
}
... and here is my client-side code using angular-file-saver ...
$http({url: "export/download/" + exportitem.exportId, withCredentials: true})
.then(function(response) {
function str2bytes(str) {
var bytes = new Uint8Array(str.length);
for (var i=0; i<str.length; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
}
var blob = new Blob([str2bytes(response.data)], {type: 'application/octet-stream'});
FileSaver.saveAs(blob, "download.zip");
}, $exceptionHandler);
The original file is 935673 bytes but response.data is 900728 and passing it through the transformation to Uint8Array results in a Blob that is 900728 in size as well. Either way, the resulting saved file is 900728 bytes (34945 bytes shy). Also it is not quite the same in what gets written. It seems to slightly get bloated but then the last part just seems to be truncated. Any ideas what I might be doing wrong?
UPDATE
I just updated my controller method to be the following and got the exact same result. Grrr.
@RequestMapping(value = "/download/{id}", method = RequestMethod.GET)
public void download(final HttpServletRequest request,
final HttpServletResponse response,
@PathVariable("id") final int id) throws IOException {
// Pseudo-code for retrieving file from ID.
Path zippath = getZipFile(id);
if (!Files.exists(zippath)) {
throw new IOException("File not found.");
}
response.setContentType("application/zip");
response.setHeader("Content-Disposition",
"attachment; filename=download.zip");
InputStream inputStream = new FileInputStream(zippath.toFile());
org.apache.commons.io.IOUtils.copy(inputStream, response.getOutputStream());
response.flushBuffer();
inputStream.close();
}
zippath.toFile()?