文件上傳和下載在web應用中很是廣泛,要在jsp環境中實現文件上傳功能是很是容易的,由於網上有許多用java開發的文件上傳組件,本文以commons-fileupload組件爲例,爲jsp應用添加文件上傳功能。common-fileupload組件是apache的一個開源項目之一,能夠從http://jakarta.apache.org/commons/fileupload/下載。用該組件可實現一次上傳一個或多個文件,並可限制文件大小。html
建立一個javaweb項目,加入common-fileupload組件(commons-fileupload-1.3.1.jar,commons-io-2.4.jar)java
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>文件上傳</title> 8 </head> 9 <body> 10 <form action="${pageContext.request.contextPath }/upload" enctype="multipart/form-data" method="post"> 11 上傳用戶:<input type="text" name="username"><br/> 12 上傳文件1:<input type="file" name="file1"><br/> 13 上傳文件2:<input type="file" name="file2"><br/> 14 <input type="submit" value="提交"> 15 </form> 16 </body> 17 </html>
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>消息提示</title> 8 </head> 9 <body> 10 ${message } 11 </body> 12 </html>
1 package com.servlet; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.util.HashMap; 8 import java.util.Iterator; 9 import java.util.List; 10 import java.util.UUID; 11 12 import javax.servlet.ServletException; 13 import javax.servlet.http.HttpServlet; 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 17 import org.apache.commons.fileupload.FileItem; 18 import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException; 19 import org.apache.commons.fileupload.ProgressListener; 20 import org.apache.commons.fileupload.disk.DiskFileItemFactory; 21 import org.apache.commons.fileupload.servlet.ServletFileUpload; 22 23 24 public class UploadServlet extends HttpServlet { 25 private static final long serialVersionUID = 1L; 26 27 28 // 定義容許上傳的文件擴展名 29 private String Ext_Name = "gif,jpg,jpeg,png,bmp,swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2"; 30 31 /** 32 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 33 * response) 34 */ 35 protected void doGet(HttpServletRequest request, HttpServletResponse response) 36 throws ServletException, IOException { 37 38 39 // 獲得上傳文件的保存目錄,將上傳文件存放在WEB-INF目錄下,不容許外界直接訪問,保證上傳文件的安全 40 String savePath = this.getServletContext().getRealPath("WEB-INF/upload"); 41 File saveFileDir = new File(savePath); 42 if (!saveFileDir.exists()) { 43 // 建立臨時目錄 44 saveFileDir.mkdirs(); 45 } 46 47 // 上傳時生成臨時文件保存目錄 48 String tmpPath = this.getServletContext().getRealPath("WEB-INF/tem"); 49 File tmpFile = new File(tmpPath); 50 if (!tmpFile.exists()) { 51 // 建立臨時目錄 52 tmpFile.mkdirs(); 53 } 54 55 // 消息提示 56 String message = ""; 57 try { 58 // 使用Apache文件上傳組件處理文件上傳步驟: 59 // 1.建立一個DiskFileItemFactory工廠 60 DiskFileItemFactory factory = new DiskFileItemFactory(); 61 // 設置工廠的緩衝區的大小,當上傳的文件大小超過緩衝區的大小時,就會生成一個臨時文件存放到指定的臨時目錄當中 62 factory.setSizeThreshold(1024 * 10);// 設置緩衝區的大小爲100KB,若是不指定,那麼默認緩衝區的大小是10KB 63 // 設置上傳時生成的臨時文件的保存目錄 64 factory.setRepository(tmpFile); 65 // 2.建立一個文件上傳解析器 66 ServletFileUpload upload = new ServletFileUpload(factory); 67 // 監聽文件上傳進度 68 upload.setProgressListener(new ProgressListener() { 69 70 @Override 71 public void update(long readedBytes, long totalBytes, int currentItem) { 72 // TODO Auto-generated method stub 73 System.out.println("當前已處理:" + readedBytes + "-----------文件大小爲:" + totalBytes + "--" + currentItem); 74 } 75 }); 76 // 解決上傳文件名的中文亂碼問題 77 upload.setHeaderEncoding("UTF-8"); 78 // 3.判斷提交上來的數據是不是上傳表單的數據 79 if (!ServletFileUpload.isMultipartContent(request)) { 80 // 按照傳統方式獲取數據 81 return; 82 } 83 84 // 設置上傳單個文件的最大值 85 upload.setFileSizeMax(1024 * 1024 * 1);// 1M 86 // 設置上傳文件總量的最大值,就是本次上傳的全部文件的總和的最大值 87 upload.setSizeMax(1024 * 1024 * 10);// 10M 88 89 List items = upload.parseRequest(request); 90 Iterator itr = items.iterator(); 91 while (itr.hasNext()) { 92 FileItem item = (FileItem) itr.next(); 93 // 若是fileitem中封裝的是普通的輸入想數據 94 if (item.isFormField()) { 95 String name = item.getFieldName(); 96 // 解決普通輸入項數據中文亂碼問題 97 String value = item.getString("UTF-8"); 98 // value = new String(value.getBytes("iso8859-1"),"UTF-8"); 99 System.out.println(name + "=" + value); 100 } else// 若是fileitem中封裝的是上傳文件 101 { 102 // 獲得上傳文件的文件名 103 String fileName = item.getName(); 104 System.out.println("文件名:" + fileName); 105 if (fileName == null && fileName.trim().length() == 0) { 106 continue; 107 } 108 // 注意:不一樣的瀏覽器提交的文件名是不同的,有些瀏覽器提交上來的文件名是帶有路徑的 109 // 如: C:\Users\H__D\Desktop\1.txt 而有些則是 : 1.txt 110 // 處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分 111 fileName = fileName.substring(fileName.lastIndexOf("\\") + 1); 112 113 // 獲得上傳文件的擴展名 114 String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); 115 // 檢查擴展名 116 // 若是須要限制上傳的文件類型,那麼能夠經過文件的擴展名來判斷上傳的文件類型是否合法 117 System.out.println("上傳的文件的擴展名是:" + fileExt); 118 if(!Ext_Name.contains(fileExt)){ 119 System.out.println("上傳文件擴展名是不容許的擴展名:" + fileExt); 120 message = message + "文件:" + fileName + ",上傳文件擴展名是不容許的擴展名:" + fileExt + "<br/>"; 121 break; 122 } 123 124 // 檢查文件大小 125 if(item.getSize() == 0) continue; 126 if(item.getSize() > 1024 * 1024 * 1){ 127 System.out.println("上傳文件大小:" + item.getSize()); 128 message = message + "文件:" + fileName + ",上傳文件大小超過限制大小:" + upload.getFileSizeMax() + "<br/>"; 129 break; 130 } 131 132 133 // 獲得存文件的文件名 134 String saveFileName = makeFileName(fileName); 135 136 //保存文件方法一// 獲取item中的上傳文件的輸入流 137 InputStream is = item.getInputStream(); 138 //建立一個文件輸出流 139 FileOutputStream out = new FileOutputStream(savePath + "\\" + saveFileName); 140 //建立一個緩衝區 141 byte buffer[] = new byte[1024]; 142 //判斷輸入流中的數據是否已經讀完的標緻 143 int len = 0; 144 while((len = is.read(buffer)) > 0){ 145 out.write(buffer, 0, len); 146 } 147 //關閉輸出流 148 out.close(); 149 //關閉輸入流 150 is.close(); 151 //刪除臨時文件 152 item.delete(); 153 154 message = message + "文件:" + fileName + ",上傳成功<br/>"; 155 156 157 //保存文件方法二 158 // File uploadedFile = new File(savePath, saveFileName); 159 // item.write(uploadedFile); 160 161 } 162 163 } 164 165 } catch (FileSizeLimitExceededException e) { 166 message = message + "上傳文件大小超過限制<br/>"; 167 e.printStackTrace(); 168 } catch (Exception e) { 169 // TODO Auto-generated catch block 170 e.printStackTrace(); 171 } finally { 172 request.setAttribute("message", message); 173 request.getRequestDispatcher("/message.jsp").forward(request, response); 174 } 175 } 176 177 /** 178 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 179 * response) 180 */ 181 protected void doPost(HttpServletRequest request, HttpServletResponse response) 182 throws ServletException, IOException { 183 // TODO Auto-generated method stub 184 doGet(request, response); 185 } 186 187 private String makeFileName(String fileName) { 188 // 爲防止文件覆蓋的現象發生,要爲上傳文件產生一個惟一的文件名 189 return UUID.randomUUID().toString().replaceAll("-", "") + "_" + fileName; 190 191 } 192 193 194 }
1 <servlet> 2 <servlet-name>UploadServlet</servlet-name> 3 <servlet-class>com.servlet.UploadServlet</servlet-class> 4 </servlet> 5 6 <servlet-mapping> 7 <servlet-name>UploadServlet</servlet-name> 8 <url-pattern>/upload</url-pattern> 9 </servlet-mapping>
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>下載文件顯示頁面</title> 9 </head> 10 <body> 11 <!-- 遍歷Map集合 --> 12 <c:forEach var="me" items="${fileNameMap}"> 13 <c:url value="/download" var="downurl"> 14 <c:param name="filename" value="${me.key}"></c:param> 15 </c:url> 16 ${me.value}<a href="${downurl}">下載</a> 17 <br /> 18 </c:forEach> 19 </body> 20 </html>
1 package com.servlet; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.HashMap; 6 import java.util.Map; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 14 public class ListFileServlet extends HttpServlet { 15 private static final long serialVersionUID = 1L; 16 17 /** 18 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 19 * response) 20 */ 21 protected void doGet(HttpServletRequest request, HttpServletResponse response) 22 throws ServletException, IOException { 23 24 // 獲取上傳文件的目錄 25 String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload"); 26 // 存儲要下載的文件名 27 Map<String, String> fileNameMap = new HashMap<String, String>(); 28 // 遞歸遍歷filepath目錄下的全部文件和目錄,將文件的文件名存儲到map集合中 29 listFile(new File(uploadFilePath), fileNameMap);// File既能夠表明一個文件也能夠表明一個目錄 30 // 將Map集合發送到listfile.jsp頁面進行顯示 31 request.setAttribute("fileNameMap", fileNameMap); 32 request.getRequestDispatcher("/listFile.jsp").forward(request, response); 33 34 } 35 36 /** 37 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 38 * response) 39 */ 40 protected void doPost(HttpServletRequest request, HttpServletResponse response) 41 throws ServletException, IOException { 42 // TODO Auto-generated method stub 43 doGet(request, response); 44 } 45 46 /** 47 * 遞歸遍歷指定目錄下的全部文件 48 * @param file 49 * @param map 50 */ 51 public void listFile(File file, Map<String, String> map) { 52 53 if(file == null) return; 54 55 // 若是file表明的不是一個文件,而是一個目錄 56 if (!file.isFile()) { 57 // 列出該目錄下的全部文件和目錄 58 File files[] = file.listFiles(); 59 if(files == null) return; 60 // 遍歷files[]數組 61 for (File f : files) { 62 // 遞歸 63 listFile(f, map); 64 } 65 } else { 66 String realName = file.getName().substring(file.getName().indexOf("_") + 1); 67 // file.getName()獲得的是文件的原始名稱,這個名稱是惟一的,所以能夠做爲key,realName是處理事後的名稱,有可能會重複 68 map.put(file.getName(), realName); 69 } 70 } 71 72 }
1 <servlet> 2 <servlet-name>ListFileServlet</servlet-name> 3 <servlet-class>com.servlet.ListFileServlet</servlet-class> 4 </servlet> 5 6 <servlet-mapping> 7 <servlet-name>ListFileServlet</servlet-name> 8 <url-pattern>/listFile</url-pattern> 9 </servlet-mapping>
1 package com.servlet; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.IOException; 6 import java.io.OutputStream; 7 import java.net.URLEncoder; 8 9 import javax.servlet.ServletException; 10 import javax.servlet.http.HttpServlet; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 public class DownloadServlet extends HttpServlet { 15 private static final long serialVersionUID = 1L; 16 17 /** 18 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 19 * response) 20 */ 21 protected void doGet(HttpServletRequest request, HttpServletResponse response) 22 throws ServletException, IOException { 23 24 // 獲得要下載的文件名 25 String fileName = request.getParameter("filename"); // 2323928392489-美人魚.avi 26 fileName = new String(fileName.getBytes("iso8859-1"), "UTF-8"); 27 // 上傳的文件都是保存在/WEB-INF/upload目錄下的子目錄當中 28 String fileSaveRootPath = this.getServletContext().getRealPath("/WEB-INF/upload"); 29 // 獲得要下載的文件 30 File file = new File(fileSaveRootPath + "\\" + fileName); 31 // 若是文件不存在 32 if (!file.exists()) { 33 request.setAttribute("message", "您要下載的資源已被刪除!!"); 34 request.getRequestDispatcher("/message.jsp").forward(request, response); 35 return; 36 } 37 // 處理文件名 38 String realname = fileName.substring(fileName.indexOf("_") + 1); 39 // 設置響應頭,控制瀏覽器下載該文件 40 response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8")); 41 // 讀取要下載的文件,保存到文件輸入流 42 FileInputStream in = new FileInputStream(fileSaveRootPath + "\\" + fileName); 43 // 建立輸出流 44 OutputStream out = response.getOutputStream(); 45 // 建立緩衝區 46 byte buffer[] = new byte[1024]; 47 int len = 0; 48 // 循環將輸入流中的內容讀取到緩衝區當中 49 while ((len = in.read(buffer)) > 0) { 50 // 輸出緩衝區的內容到瀏覽器,實現文件下載 51 out.write(buffer, 0, len); 52 } 53 // 關閉文件輸入流 54 in.close(); 55 // 關閉輸出流 56 out.close(); 57 58 } 59 60 /** 61 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 62 * response) 63 */ 64 protected void doPost(HttpServletRequest request, HttpServletResponse response) 65 throws ServletException, IOException { 66 // TODO Auto-generated method stub 67 doGet(request, response); 68 } 69 70 71 72 }
1 <servlet> 2 <servlet-name>DownloadServlet</servlet-name> 3 <servlet-class>com.servlet.DownloadServlet</servlet-class> 4 </servlet> 5 6 <servlet-mapping> 7 <servlet-name>DownloadServlet</servlet-name> 8 <url-pattern>/download</url-pattern> 9 </servlet-mapping>