1.添加文件下載工具依賴
Commons IO?is a library of utilities to assist with developing IO functionality.
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
</dependency>
2.定制文件下載頁面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件下載</title>
</head>
<body>
<div style="margin-bottom: 10px">文件下載列表:</div>
<table>
<tr>
<td>bloglogo.jpg</td>
<td><a th:href="@{/download(filename='bloglogo.jpg')}">下載文件</a></td>
</tr>
<tr>
<td>Spring Boot應用級開發教程.pdf</td>
<td><a th:href="@{/download(filename='Spring Boot應用級開發教程.pdf')}">下載文件</a></td>
</tr>
</table>
</body>
</html>
3.編寫文件下載處理辦法
FileController中添加跳轉到下載頁面的方法
@GetMapping("/toDownload")
public String toDownload(){return "download";
}
/**在fileDownload(String filename)方法中,設定了被下載文件的路徑為“F:/file/”、文件下載的打開方式和返回形式;
在獲取下載結果時,使用了commons-io的FileUtils的readFileToByteArray()方法快速下載文件,并以ResponseEntity<byte[]>類型數據返回。*/
// 文件下載管理@GetMapping("/download")public ResponseEntity<byte[]> fileDownload(String filename){// 指定要下載的文件根路徑String dirPath = "F:/file/";// 創建該文件對象File file = new File(dirPath + File.separator + filename);// 設置響應頭HttpHeaders headers = new HttpHeaders();// 通知瀏覽器以下載方式打開headers.setContentDispositionFormData("attachment",filename);// 定義以流的形式下載返回文件數據headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);try {return new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);} catch (Exception e) {e.printStackTrace();return new ResponseEntity<byte[]>(e.getMessage().getBytes(),HttpStatus.EXPECTATION_FAILED);}}
4.效果測試
在瀏覽器上訪問http://localhost:8080/toDownload
問題:下載后的文件中文名稱統一變成了“_”
中文名文件下載改進
注釋在FileController類的fileDownload()方法,
添加有中文處理方法的fileDownload(),中文處理方法getFilename(HttpServletRequest request,String filename)用來根據不同瀏覽器對下載的中文名進行轉碼。
其中,通過HttpServletRequest中的“User-Agent”用于獲取用戶下載文件的瀏覽器內核信息(不同版本的IE瀏覽器內核可能不同,需要特別查看),
如果內核信息是IE則轉碼為UTF-8,其他瀏覽器轉碼為ISO-8859-1即可。
注釋之前寫的fileDownload,添加如下的fileDownload
// 中文文件名下載管理@GetMapping("/download")public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,String filename) throws Exception{// 指定要下載的文件根路徑String dirPath = "F:/file/";// 創建該文件對象File file = new File(dirPath + File.separator + filename);// 設置響應頭HttpHeaders headers = new HttpHeaders();// 通知瀏覽器以下載方式打開(下載前對文件名進行轉碼)filename=getFilename(request,filename);headers.setContentDispositionFormData("attachment",filename);// 定義以流的形式下載返回文件數據headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);try {return new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);} catch (Exception e) {e.printStackTrace();return new ResponseEntity<byte[]>(e.getMessage().getBytes(),HttpStatus.EXPECTATION_FAILED);}}// 根據瀏覽器的不同進行編碼設置,返回編碼后的文件名private String getFilename(HttpServletRequest request, String filename)throws Exception {// IE不同版本User-Agent中出現的關鍵詞String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};// 獲取請求頭代理信息String userAgent = request.getHeader("User-Agent");for (String keyWord : IEBrowserKeyWords) {if (userAgent.contains(keyWord)) {//IE內核瀏覽器,統一為UTF-8編碼顯示,并對轉換的+進行更正return URLEncoder.encode(filename, "UTF-8").replace("+","");}}//火狐等其它瀏覽器統一為ISO-8859-1編碼顯示return new String(filename.getBytes("UTF-8"), "ISO-8859-1");}