I am currently working with jQuery and Spring Rest. jQuery is used to upload and download files to the Server. The upload process is working fine but I have little problem with downloading the files. So the scenario is, in the view, the user will select the n numbers of files to download and clicks the download button. Once the user clicks that button, the files will be downloaded. I do not want to open a new new tab for each file download. I would like to download on the same window without refreshing the current view. I looked into this but didn't help me much. Is there any way, I can achieve this?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
I answered something similar a few minutes ago: sending file from response to user, Spring REST + jQuery
I recommend you to use this JS plugin https://github.com/johnculviner/jquery.fileDownload to download the file instead using $.ajax directly. You can find all the official documentation there.
Also, in your controller, you have to take your HttpServletResponse and write the byte[] in the outputstream, and you have to put a cookie in the response to advise the JS plugin (because it needs it)
For example:
@RequestMapping(value = "/download", method = RequestMethod.GET)
public void getFilesInZIP(@RequestParam("filenames[]") String[] filenames, HttpServletResponse httpServletResponse){
byte[] file = service.packFilesToZIPArchiveAndReturnAsByteArray(filenames);
Cookie cookie = new Cookie("fileDownload", "true");
cookie.setPath("/");
httpServletResponse.addCookie(cookie);
httpServletResponse.setContentType("application/zip");
httpServletResponse.setHeader("Content-Disposition", "attachment;filename=files.zip");
httpServletResponse.getOutputStream().write(file);
}
回答2:
Here is my solution to download the file:
Spring Controller method:
@RequestMapping(value = "/download", method = RequestMethod.GET)
public void retrieveDocument(@RequestParam("id") String id, HttpServletResponse response) throws IOException {
InputStream in = fileService.getFileStream(); // My service to get the stream.
response.setContentType(MediaType.APPLICATION_OCTET_STREAM);
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
try {
IOUtils.copy(inputStream, response.getOuputStream()); //Apache commons IO.
inputStream.close();
response.flushBuffer();
response.setStatus(HttpServletResponse.SC_OK);
} catch (Exception e) {
//log error.
}
}
On client side function:
function download(id) {
var id = $('#file').attr('id')
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url here' + id, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
if(this.status == '200') {
var filename = '';
//get the filename from the header.
var disposition = xhr.getResposeHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches !== null && matches[1])
filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([this.response], {type: type});
//workaround for IE
if(typeof window.navigator.msSaveBlob != 'undefined') {
window.navigator.msSaveBlob(blob, filename);
}
else {
var URL = window.URL || window.webkitURL;
var download_URL = URL.createObjectURL(blob);
if(filename) {
var a_link = document.createElement('a');
if(typeof a.download == 'undefined') {
window.location = download_URL;
}else {
a_link.href = download_URL;
a_link.download = filename;
document.body.appendChild(a_link);
a_link.click();
}
}else {
window.location = download_URL;
}
setTimeout(function() {
URL.revokeObjectURL(download_URL);
}, 10000);
}
}else {
alert('error')';//do something...
}
};
xhr.setRequestHeader('Content-type', 'application/*');
xhr.send();
}