2015-10-07 79 views
1

我目前正在使用jQuery和Spring Rest。 jQuery被用來上傳和下載文件到服務器。上傳過程正常,但我沒有下載文件的問題。因此,在該視圖中,用戶將選擇要下載的n個文件並單擊下載按鈕。一旦用戶點擊該按鈕,文件將被下載。我不想爲每個文件下載打開一個新的新選項卡。我想在不刷新當前視圖的情況下在同一窗口下載。我看着this,但沒有多大幫助。有什麼辦法,我可以做到這一點?Spring Rest和jQuery Ajax文件下載

回答

0

這裏是我的解決方案,以下載文件:

春控制器的方法:

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

我回答類似的東西在幾分鐘前:我建議你使用這個JS插件https://github.com/johnculviner/jquery.fileDownload下載使用,而不是直接$就文件sending file from response to user, Spring REST + jQuery


。你可以在那裏找到所有的官方文檔。

而且,在你的控制器,你得把你的HttpServletResponse譜寫OutputStream的字節[],你必須把一個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); 

    } 
+0

雖然此鏈接可以回答這個問題,最好是在這裏有答案的主要部件,並提供鏈接以供參考。如果鏈接頁面更改,則僅鏈接答案可能會失效。 - [來自評論](/ review/low-quality-posts/10266851) –

+0

這是另一個線程中的另一個問題。我更願意給他與我的答案的鏈接,而不是複製+粘貼 – Roman

+0

瞭解。不過,我們通常儘量避免在StackOverflow中使用僅鏈接的答案。 (這裏有一些[相關討論](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers)。)鏈接在一個完美的罰款評論,或者你可以嘗試提煉答案的關鍵點以及鏈接。 –