文件上傳功能在網頁中見的太多了,好比上傳照片做爲頭像、上傳Excel文檔導入數據等html
先寫個上傳文件的htmljava
<!DOCTYPE html> <html> <head> <title>Spring MVC文件上傳與下載</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <form action="upload" method="POST" enctype="multipart/form-data"> <!-- 上傳文件注意enctype --> 文件描述:<input type="text" name="desc" /> <br><br> 選擇文件:<input type="file" name="file" /> <br><br> <input type="submit" value="上傳" /> </form> </body> </html>
寫個controller接收上傳的文件web
package net.sonng.mvcdemo.controller; import java.io.File; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; @Controller public class UploadController { @RequestMapping("/upload") public String upload(HttpServletRequest request,@RequestParam("desc") String desc,@RequestParam("file") MultipartFile file) throws Exception{ //接收到的文件綁定到MultipartFile對象中 System.out.println(desc); if (!file.isEmpty()){ //若是文件不爲空,那麼將它存起來 String path=request.getServletContext().getRealPath("/images"); //接收的文件放在/images目錄下,並得到文件系統目錄 String filename=file.getOriginalFilename();//獲取文件名 File filepath=new File(path,filename); //根據文件所在目錄和文件名建立File對象 if(!filepath.getParentFile().exists()){ //若是所在目錄不存在,那麼建立 filepath.getParentFile().mkdirs(); } file.transferTo(new File(path+File.separator+filename)); //調用transferTo()方法將文件存儲到目標位置 //file.transferTo(filepath) //也能夠用這條語句 return "result"; }else{ return "error"; } } }
經常使用方法有:spring
Spring MVC的文件上傳組件須要MultipartResolver接口,依賴於Apache Commons FileUpload技術實現了一個實現類CommonsMultipartResolver,所以還須要兩方面的工做:1. 引入Apache Commons FileUpload包;2. 配置xmlapache
引入Apache Commons FileUpload及其依賴的Commons IO瀏覽器
配置xmlmvc
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize"> <!-- 還能夠限制上傳文件的大小 --> <value>10485760</value> </property> <property name="defaultEncoding" > <!-- 注意這個編碼格式,要跟上傳的頁面的編碼一致 --> <value>UTF-8</value> </property> </bean>
部署訪問,檢查Tomcat的該app目錄下的/images目錄下是否有上傳的文件。app
好比頭像,老是屬於某個用戶,所以在用戶類中能夠定義一個MultipartFile屬性存儲用戶頭像
上傳用戶頭像的htmljsp
<!DOCTYPE html> <html> <head> <title>Spring MVC文件上傳與下載</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <form action="upload" method="POST" enctype="multipart/form-data"> 用戶名:<input type="text" name="username" /> <br><br> 選擇圖片:<input type="file" name="avatar" /> <br><br> <input type="submit" value="上傳" /> </form> </body> </html>
實體類user:測試
package net.sonng.mvcdemo.entity; import org.springframework.web.multipart.MultipartFile; public class User { private String username; private MultipartFile avatar; //上傳的頭像做爲User的一個屬性 //。。。。。 }
寫controller:
package net.sonng.mvcdemo.controller; import java.io.File; import javax.servlet.http.HttpServletRequest; import net.sonng.mvcdemo.entity.User; import org.apache.commons.io.FileUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class UploadController { @RequestMapping("/upload") public String upload(HttpServletRequest request,@ModelAttribute User user,Model model) throws Exception{ if (!user.getAvatar().isEmpty()){ String path=request.getServletContext().getRealPath("/avatars/"); String filename=user.getAvatar().getOriginalFilename(); File filepath=new File(path,filename); if(!filepath.getParentFile().exists()){ filepath.getParentFile().mkdirs(); } user.getAvatar().transferTo(new File(path+File.separator+filename)); model.addAttribute("user", user); return "result"; }else{ return "error"; } } @RequestMapping("/download") //上傳了以後再下載 public ResponseEntity<byte[]> download(HttpServletRequest request,@RequestParam("filename") String filename,Model model)throws Exception{ String path=request.getServletContext().getRealPath("/avatars/"); //獲取文件所在路徑 filename=new String(filename.getBytes("ISO-8859-1"),"UTF-8"); //不知何故,result.jsp的請求參數是ISO-8859-1編碼的,但明明設置了charset=utf-8 File file=new File(path+File.separator+filename); HttpHeaders headers=new HttpHeaders(); String downloadFileName=new String(filename.getBytes("UTF-8"),"ISO-8859-1"); //少了這句,可能致使下載中文文件名的文檔,只有後綴名的狀況 headers.setContentDispositionFormData("attachment", downloadFileName);//告知瀏覽器如下載方式打開 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//設置MIME類型 return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.CREATED);// //用FileUpload組件的FileUtils讀取文件,並構建成ResponseEntity<byte[]>返回給瀏覽器 //HttpStatus.CREATED是HTTP的狀態碼201 } }
上傳成功後,返回頁面result.jsp,
<%@page pageEncoding="utf-8" contentType="text/html;charset=utf-8" %> <html> <head> <title>文件的上傳與下載</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <p>下載剛纔上傳的文件</p> <a href="download?filename=${user.avatar.originalFilename }">下載文件</a> </body> </html>
部署測試,分別測試中文/英文文件名
上傳文件:上傳的文件綁定到MultipartFile中;獲取文件名;要存儲的文件系統路徑;建立目錄;用MultipartFile的transferTo()存儲 下載文件:獲取要下載的文件名,注意編碼;在HttpHeaders中設置如下載方式打開,設置MIME類型;用FileUtils.readFileToByteArray()讀取文件數據;用ResponseEntity<byte[]>構建返回對象