版權聲明:本文為部落客原創文章,如需轉載,請标明出處。 https://blog.csdn.net/alan_liuyue/article/details/72771926
一、前言
上一篇文章我們了解了,通過Java的io輸出流來實作普通的檔案下載下傳的功能,是廣大程式員在做項目中會普遍使用到的下載下傳檔案的方法。但是,在項目中我們都基本上是用架構在開發,是以,我們同時也需要學習每個架構的針對性的檔案下載下傳方法,這對于使用架構開發來說,不失為更加有效的一種方法,畢竟使用架構封裝好的方法有時會更加節省時間。
那麼,本篇部落格則會将重點放在springmvc架構的檔案下載下傳功能方面,話不多說,切入主題:
二、架構内部執行個體
1.一般需要配置的jar包:
commons.fileupload-1.2.1.jar和commons.io-1.4.0.jar,
點選下載下傳jar包 2.xml配置:<!-- 轉換json格式,使用ResponseBody注解 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<!--此bean配置需放在mapping的配置之前,用于處理檔案下載下傳的responseEntity的傳回值-->
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<ref bean="mappingJackson2HttpMessageConverter" />
</list>
</property>
</bean>
<bean id="mappingJackson2HttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>text/json;charset=UTF-8</value>
</list>
</property>
</bean>
3.方法執行個體:
//檔案下載下傳,使用spring特有的responseEntity<byte[]>工具下載下傳檔案
//使用ResponseEntity<byte[]>傳回值,同時設定HttpHeaders傳回類型,則前台就會自動彈出下載下傳框
@RequestMapping("/downloadFile")
public ResponseEntity<byte[]> downloadFile(String fileName,HttpServletRequest request) throws IOException{
//擷取檔案的根路徑
String realPath = request.getSession().getServletContext().getRealPath("/upload");
//列印測試前台傳遞的檔案名(包含檔案格式,例如"test.jpg"),springmvc設定自動比對
System.out.println("檔案開始下載下傳!擷取到的檔案名:"+fileName);
//根據檔案名擷取檔案具體路徑,建立檔案
File file = new File(realPath+File.separator+fileName);
//将檔案輸入流
InputStream is = new FileInputStream(file);
byte[] buff = null;
buff = new byte[is.available()]; //擷取檔案的實際可讀位元組數,即擷取檔案總大小
is.read(buff); //讀取檔案,使用byte位元組數組存儲
//設定傳回類型和下載下傳名稱,設定之後前台會自動彈窗下載下傳
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attchement;filename=" + file.getName());
HttpStatus statusCode = HttpStatus.OK;
ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(buff, headers, statusCode);
return entity;
}
三、架構外部執行個體
1.有時候我們不習慣去用架構内部的下載下傳方法去下載下傳,是以這裡也順便提供使用普通的方法去進行單檔案下載下傳或者多檔案打包下載下傳:
2. 方法執行個體:
/**
* 單檔案下載下傳或多檔案壓縮打包下載下傳,入口
* @param request
* @param response
* @throws IOException
*/
@RequestMapping(value = "/downloadFiles")
public String downloadFiles(HttpServletRequest request,HttpServletResponse response) throws IOException {
/**
* 多檔案壓縮下載下傳
*/
//壓縮檔案的名稱和臨時路徑
String zipName = "download.zip";
String zipPath=request.getSession().getServletContext().getRealPath("/upload/zip");
String zipCompletePath = zipPath+File.separator+zipName;
//需要下載下傳的檔案集合的檔案夾
String path = request.getSession().getServletContext().getRealPath("/upload/fileDir");
//周遊擷取檔案夾的所有檔案,将完整路徑放入list集合
File file = new File(path);
File[] filePathArr = file.listFiles();//檔案數組
List<String> filePaths = new ArrayList<String>();//檔案路徑集合
for(File fileTem: filePathArr) {
filePaths.add(fileTem.toString());
}
//打包壓縮下載下傳
this.downloadZip(zipPath,zipName,zipCompletePath,filePaths,response);
//删除臨時檔案
File zip = new File(zipPath);
zip.delete();
file.delete();
/**
* 單檔案下載下傳
*/
/*
String filePath = path;
String fileName = "test.jpg";
this.downloadFile(filePath, fileName, response);
*/
return null;
}
/**
* 多檔案壓縮打包下載下傳,可單獨作為工具類剝離出來
* @param zipPath 壓縮檔案臨時路徑
* @param zipName 壓縮檔案名稱
* @param zipCompletePath 壓縮檔案完成路徑+名稱
* @param filePaths 需要壓縮的檔案清單
* @param response
* @throws IOException
*/
public void downloadZip(String zipPath,String zipName,String zipCompletePath,List<String>filePaths,HttpServletResponse response) {
try {
//驗證壓縮包是否存在,不存在則重新建立
File tmpZip=new File(zipPath);
if (!tmpZip.exists()) {
tmpZip.mkdirs();
}
File tmpZipFile = new File(zipCompletePath);
if (!tmpZipFile.exists()) {
tmpZipFile.createNewFile();
}
//使用壓縮輸出流往壓縮包寫入資料
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipCompletePath));
for (int i = 0; i < filePaths.size(); i++) {
File temfile = new File(filePaths.get(i));
FileInputStream fis = new FileInputStream(temfile);//建立檔案輸入流讀取檔案資料
zos.putNextEntry(new ZipEntry(temfile.getName()));
int size = 0;
byte[] buffer = new byte[1024]; //設定讀取資料緩存大小
while ((size = fis.read(buffer)) > 0) {
zos.write(buffer, 0, size);
}
zos.closeEntry();
fis.close();
}
zos.close();//關閉壓縮輸出流
//用下載下傳普通檔案方法下載下傳壓縮封包件
downloadFile(zipPath,zipName,response);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 單檔案下載下傳,可單獨作為工具類剝離出來
* @param fileName
* @param filePath
* @param response
*/
public void downloadFile(String filePath,String fileName,HttpServletResponse response){
try {
//使用輸入流讀取檔案資料
File file=new File(filePath,fileName);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file.getPath()));
byte[] buffer = new byte[bis.available()];//從輸入流中讀取不受阻塞
bis.read(buffer);
bis.close();
//設定輸出響應格式
response.reset();//清除首部的空白行
response.setCharacterEncoding("utf-8"); //設定輸出字元編碼
response.setContentType("application/octet-stream"); //設定下載下傳類型
response.setHeader("Content-Disposition", "attachment;filename=" + fileName); //設定下載下傳檔案名稱
//使用輸出流往用戶端輸出資料
OutputStream ost = new BufferedOutputStream(response.getOutputStream());
ost.write(buffer);
ost.flush();//釋放緩存
ost.close();//關閉輸出流
}
catch (IOException ex) {
ex.printStackTrace();
}
}
四、總結
1.檔案下載下傳的方法思路基本都是:擷取前台傳遞的檔案名》擷取檔案的根路徑》拼接完整路徑》建立具體 檔案》使用輸入流讀取檔案》設定傳回值為下載下傳類型》使用輸出流将檔案輸出到用戶端,而其中實作這些步驟的方法 程式員可自行去編寫和設定,不過基本都是大同小異,而架構也基本是封裝了這些方法,讓程式員節省更多的步驟和 時間成本,了解其中的原理之後程式員在面對各個架構的時候都基本上能夠得心應手;
2.springmvc在處理檔案下載下傳方面,使用了ResponseEntity這個傳回類型來處理檔案寫入用戶端的功能,在使用之前記得去配置相應的xml,以免出錯;
3.有時程式員不希望再增加過多的配置,為了友善,可直接使用普通的方法去單檔案或者多檔案打包下載下傳,這也是在開發過程中很常用的方法;
4.實踐是檢驗認識真理性的唯一标準,根據代碼和注釋多進行嘗試,則很快就會明白其中的原理
上一篇:
java檔案下載下傳功能代碼(單檔案下載下傳、多檔案批量打包下載下傳)——普遍适用下一篇:
ssh架構之struts2檔案下載下傳功能代碼