這裏我們來總結整理一下常用的兩種文件上傳方式以及要注意的東西:
1、springmvc .MultipartFile 的上傳方式。
2、org.apache.commons.fileupload 使用apache的fileuoload 來實現
當我們使用springmvc 的MultipartFile 時我們要在spring的配置文件中添加如下的配置文件:
(1)、bean的引入以及編碼和上傳文件大小兩個屬性的設置
- <bean id="multipartResolver"
- class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="defaultEncoding" value="UTF-8" />
- <property name="maxUploadSize" value="2000000000" />
- </bean>
(2)、控制層的代碼:
- public void upload2(HttpServletRequest request) {
- // 轉型爲MultipartHttpRequest
- try {
- MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
- List<MultipartFile> fileList = multipartRequest.getFiles("file");
- for (MultipartFile mf : fileList) {
- if(!mf.isEmpty()){
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
這樣就簡單的獲取了上傳文件,其實我們上傳的文件就是一個MultipartFile 對象,獲取了對象後我們就可以獲取文件名以及輸入流。
(3)、控制層的第二種方式:
- public String upload(HttpServletRequest request,
- @RequestParam(value = "file") MultipartFile[] files) {
- try {
- for (MultipartFile mf : files) {
- if(!mf.isEmpty()){
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return "upload";
- }
(2)、(3)、不管哪種,其實都是一樣的原理,都是將上傳文件轉化爲了對象。
這裏springMVC 都爲我們封裝好成自己的文件對象了,轉換的過程就在我們所配置的CommonsMultipartResolver這個轉換器裏面下面再來看看它的源碼
看到這個你應該明白了,如果你配置了multipartResolver 這個bean 則程序會自動調用fileUpload 來解析request ,在控制層獲取的request已經是被解析過的,所以不用在手動去調用fileUpload 的相關方法來解析這個request。但注意,如果在spring的配置文件中沒有配置這個bean的話,則我們自己要在controller層調用fileUpload 的相關方法來解析request 。ok這裏說了第一種使用springmvc 的MultipartFile ,但是第二種和第一種其實是一樣的,第一種解析的過程由spring替我們幹了,我們只需要獲取數據就ok而第二種方式就是在spring 的配置文件中不配置bean 這樣在控制層中我們只能自己去解析請求。
所以簡單的來說其實就是一種技術的兩種使用方式,第一種是配置在了spring 容器中而第二種就是不配置在spring容器中而是自己去解析請求信息。
注意:剛開始學習的時候,你肯能不瞭解而出現了獲取不到數據的這種情況,那就是在你不知不覺中解析了兩次request所以你獲取不到你想要的數據,那怎麼處理那其實很簡單,具體看下面:
1、不在spring的配置文件中配置,則需要你在控制層調用fileupload 的方法進行解析:
- @RequestMapping(value="/upload.do")
- @SuppressWarnings("unchecked")
- public void upload(HttpServletRequest request,HttpServletResponse response) throws IOException, FileUploadException{
- System.out.println("文件存放目錄、臨時文件目錄準備完畢 ...");
- System.out.println("filePath-->:"+filePath);
- System.out.println("tempPath-->:"+tempPath);
- response.setContentType("text/plain;charset=utf-8");
- PrintWriter pw = response.getWriter();
- // 磁盤文件工廠,創建緩存文件
- DiskFileItemFactory diskFactory = new DiskFileItemFactory();
- // threshold 極限、臨界值,即磁盤緩存大小設置
- diskFactory.setSizeThreshold(10*4 * 1024);
- // repository 貯藏室,即臨時文件目錄 ,設置文件的緩存路徑
- diskFactory.setRepository(new File(tempPath));
- ServletFileUpload upload = new ServletFileUpload(diskFactory);
- // 設置允許上傳的最大文件大小 ,如果是-1表示沒有限制
- upload.setSizeMax(10 * 1024 * 1024);
- //解決上傳的文件名亂碼
- upload.setHeaderEncoding("UTF-8");
- // 3、判斷用戶的表單提交方式是不是multipart/form-data,這也是我們在form中設置的那個屬性的值 是不是……
- boolean bb = upload.isMultipartContent(request);
- if (!bb) {
- return ;
- }
- // 解析HTTP請求消息頭 ,也就是調用方法解析提交的內容並將其組裝成一個個的FileItem對象
- // 而其中上傳的一個文件就是一個FileItem對象
- List<FileItem> fileItems = upload.parseRequest(request);
- try {
- Iterator<FileItem> iter = fileItems.iterator();
- while(iter.hasNext())
- {
- FileItem item = (FileItem)iter.next();
- //按照給定的編碼格式獲取上傳文件內容
- String fieldValue = item.getString("UTF-8");
- //獲取標籤名稱
- String tagName = item.getFieldName();
- //獲取文件名稱
- String fileName= item.getName();
- //上傳文件輸入流,也就是整個上傳文件的流
- InputStream input = item.getInputStream();
- System.out.println("tagName--->:"+tagName +"fileName--->"+fileName );
- //判斷這個FileItem是不是表單屬性(他能判斷是上傳的文件還是表單屬性)
- if(item.isFormField())
- {
- System.out.println("處理表單內容 ...");
- processFormField(item, pw);
- }else{
- System.out.println("處理上傳的文件 ...");
- processUploadFile(item, pw);
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally{
- pw.close();
- }
- }
- /**
- * 處理表單內容
- * @param item
- * @param pw
- * @throws Exception
- */
- private void processFormField(FileItem item, PrintWriter pw)
- throws Exception
- {
- String tagName = item.getFieldName();
- String fileName = item.getString("utf-8");
- pw.println(tagName + " : " + fileName + "\r\n");
- }
- /**
- * 處理上傳的文件
- * @param item
- * @param pw
- * @throws Exception
- */
- private void processUploadFile(FileItem item, PrintWriter pw)
- throws Exception
- {
- //文件名稱
- String filename = item.getName();
- System.out.println("完整的文件名:" + filename);
- //上傳文件大小(byte)
- long fileSize = item.getSize();
- if("".equals(filename) && fileSize == 0)
- {
- System.out.println("文件名爲空 ...");
- return;
- }
- System.out.println("filePath:-->"+filePath);
- System.out.println("filename:--->"+filename);
- //創建保存文件路徑
- File uploadFile = new File(filePath +File.separator + filename);
- if(!uploadFile.getParentFile().exists()){
- uploadFile.getParentFile().mkdirs();
- }
- uploadFile.createNewFile();
- //將上傳上來的文件內容寫到指定的文件
- item.write(uploadFile);
- //向瀏覽器打印
- pw.println(filename + " 文件保存完畢 ...");
- pw.println("文件大小爲 :" + fileSize + "\r\n");
- }
2、在spring的配置文件中配置了這個bean 則不在需要我們自己調用一個fileupload 的方法再去解析一次,而是直接使用:
- /**
- * spring mvc MultipartFile 多文件上傳
- * @param request
- * @param response
- * @throws IOException
- */
- @RequestMapping(value="/upload1.do")
- public void upload1(HttpServletRequest request,HttpServletResponse response) throws IOException{
- //創建一個通用的多部分解析器
- CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
- //判斷用戶的表單提交方式是不是multipart/form-data,這也是我們在form中設置的那個屬性的值 是不是……
- if(multipartResolver.isMultipart(request)){
- //判斷 request 是否有文件上傳,即多部分請求
- MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
- //獲取所有上傳文件的名稱是input標籤中的名稱
- Iterator<String> iter = multipartRequest.getFileNames();
- while(iter.hasNext()){
- String name = iter.next();
- //按照文件名稱獲取這個上傳文件,上傳文件被轉化爲MultipartFile 對象
- MultipartFile file= multipartRequest.getFile(name);
- //獲取文件名,這裏的fname也是input標籤中的name而不是文件名
- String fname= file.getName();
- //這裏獲取到的纔是真真的文件名稱 比如test.txt等這樣的名稱。
- String myfname= file.getOriginalFilename();
- //獲取輸入流
- InputStream input = file.getInputStream();
- System.out.println("fname: "+fname +" name: "+name +" myfname:"+myfname);
- }
- //這的getFiles("file")就是獲取多個input標籤名稱爲file的文件。
- List<MultipartFile> fileList = multipartRequest.getFiles("file");
- for(MultipartFile file:fileList){
- System.out.println("----fileList size:"+fileList.size());
- //獲取input標籤中的名稱
- String name= file.getName();
- //這裏獲取到的纔是真真的文件名稱 比如test.txt等這樣的名稱。
- String myfname= file.getOriginalFilename();
- //獲取這個文件的輸入流
- InputStream input = file.getInputStream();
- System.out.println("name"+name +"myfname:"+myfname);
- }
- }
- PrintWriter p= response.getWriter();
- p.write("ok!!!");
- }