Spring Rest和jQuery Ajax文件下载

时间:2015-10-07 14:58:05

标签: javascript jquery ajax spring spring-mvc

我目前正在使用jQuery和Spring Rest。 jQuery用于将文件上载和下载到服务器。上传过程工作正常但我下载文件没什么问题。因此,在视图中,用户将选择要下载的n个文件并单击下载按钮。用户单击该按钮后,将下载文件。我不想为每个文件下载打开一个新的新选项卡。我想在同一窗口下载而不刷新当前视图。我调查了this,但对我帮助不大。有什么办法,我能做到吗?

2 个答案:

答案 0 :(得分:1)

几分钟前我回答了类似问题:sending file from response to user, Spring REST + jQuery

我建议您使用此JS插件https://github.com/johnculviner/jquery.fileDownload直接使用$ .ajax下载文件。你可以在那里找到所有的官方文件。

此外,在你的控制器中,你必须使用你的HttpServletResponse并在输出流中写入byte [],你必须在响应中放入一个cookie来建议JS插件(因为它需要它)

例如:

@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);

    }

答案 1 :(得分:1)

以下是我下载文件的解决方案:

Spring Controller方法:

@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.
    }

}

在客户端功能:

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();
}