javascript
channelsftp 上传文件为空_SpringBoot文件上传下载篇(九)
點(diǎn)擊上方藍(lán)色字體,關(guān)注我們
上傳文件是互聯(lián)網(wǎng)中應(yīng)用的場(chǎng)景之一,最典型的情況就是上傳頭像。文件上傳主要是將文件通過(guò)IO流傳輸?shù)椒?wù)器的某一個(gè)特定的文件夾下。
Why->MultipartFile?解析源碼:
public?interface?MultipartFile?extends?InputStreamSource?{}
public?class?MockMultipartFile?extends?Object?implements?MultipartFile?implements?MultipartFile,?Serializable?{
}
public?class?CommonsMultipartFile?implements?MultipartFile,?Serializable?{
}
public?interface?MultipartFile?extends?InputStreamSource?{
}
通過(guò)源碼可以看出?MultipartFile是一個(gè)接口,這個(gè)接口的實(shí)現(xiàn)類有?CommonsMultipartFile,MockMultipartFile,MultipartFile繼承InputStreamSource這個(gè)接口。
MultipartFile--String?getName()?//返回表單中file文件參數(shù)name的名稱。
--String?getOriginalFilename()?//?文件原名稱
--String?getContentType()?//返回文件的內(nèi)容類型。
--boolean?isEmpty()?// 返回上傳的文件是否為空,即,在多部分表單中沒(méi)有選擇任何文件,或者所選文件沒(méi)有內(nèi)容。
--long?getSize()?// 以字節(jié)為單位返回文件的大小。
--byte[]?getBytes()?//將文件的內(nèi)容作為字節(jié)數(shù)組返回。
--InputStream?getInputStream()?//返回一個(gè)InputStream以從中讀取文件的內(nèi)容。
--void?transferTo(File?dest)?//將收到的文件傳輸?shù)浇o定的目標(biāo)文件。
參考官網(wǎng)地址
https://docs.spring.io/spring/docs/current/javadoc-
api/org/springframework/web/multipart/MultipartFile.html
開(kāi)始搭建環(huán)境jdk1.8,引入了spring-boot-starter-thymeleaf做頁(yè)面模板引擎。
?<properties>????<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-devtoolsartifactId>
????<optional>trueoptional>
dependency>
dependencies>
application.properties配置文件
#thymeleafspring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
#?禁用?thymeleaf?緩存
spring.thymeleaf.cache=false
#?上傳文件總的最大值
spring.servlet.multipart.max-request-size=10MB
#?單個(gè)文件的最大值
spring.servlet.multipart.max-file-size=10MB
#?是否支持批量上傳???(默認(rèn)值?true)
spring.servlet.multipart.enabled=true
#?上傳文件的臨時(shí)目錄?(一般情況下不用特意修改)
spring.servlet.multipart.location=
#?文件大小閾值,當(dāng)大于這個(gè)閾值時(shí)將寫(xiě)入到磁盤(pán),否則存在內(nèi)存中,(默認(rèn)值0?一般情況下不用特意修改)
spring.servlet.multipart.file-size-threshold=0
#?判斷是否要延遲解析文件(相當(dāng)于懶加載,一般情況下不用特意修改)
spring.servlet.multipart.resolve-lazily=false
常見(jiàn)問(wèn)題:
1、表單method設(shè)置為post,并將enctype設(shè)置為multipart/form-data。
2、html中name值要和@RequestParam("file")中的值保持一致。
3、上傳文件大小spring.http.multipart.max-file-size限制,如果上傳的文件超過(guò)設(shè)置的值會(huì)出現(xiàn)這個(gè)錯(cuò)誤。
這個(gè)錯(cuò)誤是因?yàn)镾pring文件上傳重置問(wèn)題,這個(gè)異常是捕獲不到,需要Tomcat的默認(rèn)連接器?maxSwallowSize?的參數(shù)。
<Connector?port="8080"?protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"maxSwallowSize="-1"?/>并在上傳前實(shí)現(xiàn)Javascript檢查文件大小。
單文件上傳
單文件上傳html頁(yè)面
html><html?lang="en">
<head>
???<meta?charset="UTF-8">
???<title>單文件上傳title>
head>
?<body>
?<p>單文件上傳p>
<form?method="POST"?enctype="multipart/form-data"?action="/upload"?>
文件:<input?type="file"?name="file"/>
??????<input?type="submit"/>
form>
<hr/>
body>
創(chuàng)建FileUploadController中的upload方法 (單文件上傳)
@PostMapping("/upload")@ResponseBody
public?String?upload(@RequestParam("file")?MultipartFile?file)?{
????//判斷非空
????if?(file.isEmpty())?{
????????return?"上傳的文件不能為空";
????}
????try?{
????????//?測(cè)試MultipartFile接口的各個(gè)方法
????????logger.info("[文件類型ContentType]?-?[{}]",file.getContentType());
????????logger.info("[文件組件名稱Name]?-?[{}]",file.getName());
????????logger.info("[文件原名稱OriginalFileName]?-?[{}]",file.getOriginalFilename());
????????logger.info("[文件大小]?-?[{}]",file.getSize());
????????logger.info(this.getClass().getName()+"圖片路徑:"+path);
????????File?f?=?new?File(path);
????????//?如果不存在該路徑就創(chuàng)建
????????if?(!f.exists())?{
????????????f.mkdir();
????????}
????????File?dir?=?new?File(path?+?file.getOriginalFilename());
????????//?文件寫(xiě)入
????????file.transferTo(dir);
????????return?"上傳單個(gè)文件成功";
????}?catch?(Exception?e)?{
????????e.printStackTrace();
????????return?"上傳單個(gè)文件失敗";
????}
}
注:這里除了transferTo方法,也可以用字節(jié)流的方式上傳文件,但是字節(jié)流比較慢,所以還是建議用transferTo,下面這個(gè)方法是封裝的一個(gè)用字節(jié)流寫(xiě)入文件的方法。
??public?void?writeFile(MultipartFile?file)?{????try?{
????????//獲取輸出流
????????OutputStream?os?=?new?FileOutputStream(path?+?file.getOriginalFilename());
????????//獲取輸入流?CommonsMultipartFile?中可以直接得到文件的流
????????InputStream?is?=?file.getInputStream();
????????byte[]?buffer?=?new?byte[1024];
????????//判斷輸入流中的數(shù)據(jù)是否已經(jīng)讀完的標(biāo)識(shí)
????????int?length?=?0;
????????//循環(huán)將輸入流讀入到緩沖區(qū)當(dāng)中,(len=in.read(buffer))>0就表示in里面還有數(shù)據(jù)
????????while((length?=?is.read(buffer))!=-1){
????????????//使用FileOutputStream輸出流將緩沖區(qū)的數(shù)據(jù)寫(xiě)入到指定的目錄(savePath?+?"\\"?+?filename)當(dāng)中
????????????os.write(buffer,?0,?length);
????????}
????????os.flush();
????????os.close();
????????is.close();
????}?catch?(FileNotFoundException?e)?{
????????e.printStackTrace();
????}?catch?(IOException?e)?{
????????e.printStackTrace();
????}
}
操作步驟
單文件上傳完成啦,接下來(lái)就是多文件上傳和文件下載。
多文件上傳
html頁(yè)面
html><html?lang="en">
<head>
<meta?charset="UTF-8">
<title>多文件上傳title>
head>
<body>
<p>多文件上傳p>
<form?method="POST"?enctype="multipart/form-data"?action="/uploadBatch">
????<p>文件1:<input?type="file"?name="file"/>p>
????<p>文件2:<input?type="file"?name="file"/>p>
????<p><input?type="submit"?value="上傳"/>p>
form>
body>
html>
uploadBatch方法
@PostMapping("/uploadBatch")@ResponseBody
public?String?uploadBatch(@RequestParam("files")?MultipartFile[]?files)?{
????logger.info("文件名稱:"+?files?);
????if(files!=null&&files.length>0){
????????String?filePath?=?"D:\\datafile\\";
????????for?(MultipartFile?mf?:?files)?{
????????????//?獲取文件名稱
????????????String?fileName?=?mf.getOriginalFilename();
????????????//?獲取文件后綴
????????????String?suffixName?=?fileName.substring(fileName.lastIndexOf("."));
????????????//?重新生成文件名
????????????fileName?=?UUID.randomUUID()+suffixName;
????????????if?(mf.isEmpty())?{
????????????????return?"文件名稱:"+?fileName?+"上傳失敗,原因是文件為空!";
????????????}
????????????File?dir?=?new?File(filePath?+?fileName);
????????????try?{
????????????????//?寫(xiě)入文件
????????????????mf.transferTo(dir);
????????????????logger.info("文件名稱:"+?fileName?+"上傳成功");
????????????}?catch?(IOException?e)?{
????????????????logger.error(e.toString(),?e);
????????????????return?"文件名稱:"+?fileName?+"上傳失敗";
????????????}
????????}
????????return?"多文件上傳成功";
????}
????return?"上傳文件不能為空";
}
操作步驟
常見(jiàn)問(wèn)題
The?field?file?exceeds?its?maximum?permitted?size?of?1048576?bytes.這個(gè)錯(cuò)誤是由于springboot默認(rèn)的文件大小是1MB造成的,當(dāng)上傳文件超過(guò)1MB時(shí)就會(huì)報(bào)錯(cuò)。解決這個(gè)報(bào)錯(cuò)可以在application.properties中設(shè)置上傳參數(shù),參數(shù)項(xiàng)是默認(rèn)的,我們?cè)O(shè)置最大上傳文件大小不超過(guò)10MB,再次上傳會(huì)成功。
文件下載方法
@GetMapping("/downloadfile")@ResponseBody
public?String?downloadFile(HttpServletRequest?request,?HttpServletResponse?response)?throws?UnsupportedEncodingException?{
????String?fileName?=?"大話設(shè)計(jì)模式(帶目錄完整版).pdf";//?文件名
????if?(fileName?!=?null)?{
????????//設(shè)置文件路徑
????????File?file?=?new?File("D:\\datafile\\大話設(shè)計(jì)模式(帶目錄完整版).pdf");
????????//File?file?=?new?File(realPath?,?fileName);
????????if?(file.exists())?{
????????????response.setContentType("multipart/form-data");
????????????response.setHeader("Content-Disposition",?"attachment;?fileName="+??fileName?+";filename*=utf-8''"+?URLEncoder.encode(fileName,"UTF-8"));
????????????byte[]?buffer?=?new?byte[1024];
????????????FileInputStream?fis?=?null;
????????????BufferedInputStream?bis?=?null;
????????????try?{
????????????????fis?=?new?FileInputStream(file);
????????????????bis?=?new?BufferedInputStream(fis);
????????????????OutputStream?os?=?response.getOutputStream();
????????????????int?i?=?bis.read(buffer);
????????????????logger.info(""+i);
????????????????while?(i?!=?-1)?{
????????????????????os.write(buffer,?0,?i);
????????????????????i?=?bis.read(buffer);
????????????????}
????????????????return?"下載成功";
????????????}?catch?(Exception?e)?{
????????????????e.printStackTrace();
????????????}?finally?{
????????????????if?(bis?!=?null)?{
????????????????????try?{
????????????????????????bis.close();
????????????????????}?catch?(IOException?e)?{
????????????????????????e.printStackTrace();
????????????????????}
????????????????}
????????????????if?(fis?!=?null)?{
????????????????????try?{
????????????????????????fis.close();
????????????????????}?catch?(IOException?e)?{
????????????????????????e.printStackTrace();
????????????????????}
????????????????}
????????????}
????????}
????}
????return?"文件不存在";
}
在下載文件時(shí),中文文件名稱會(huì)出現(xiàn)亂碼問(wèn)題,需要設(shè)置一下即可。
response.setHeader("Content-Disposition",?"attachment;?fileName="+??fileName?+";filename*=utf-8''"+?URLEncoder.encode(fileName,"UTF-8"));總結(jié)下載的html頁(yè)面我就不復(fù)制啦,一個(gè)Spring Boot 上傳和下載文件的簡(jiǎn)單 Demo 就完成了,感興趣的同學(xué)可以將示例代碼下載下來(lái)試試吧。
GitHub:
https://github.com/xiaonongOne/springboot-upload
總結(jié)
以上是生活随笔為你收集整理的channelsftp 上传文件为空_SpringBoot文件上传下载篇(九)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: jvm垃圾回收机制_JVM 垃圾回收机制
- 下一篇: drcom linux怎么运行,Drco