<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>文件上傳</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="${pageContext.request.contextPath}/servlet/UploadServlet" method="post" enctype="multipart/form-data"> name:<input name="name"/><br/> file1:<input type="file" name="f1"/><br/> <input type="submit" value="上傳"> </form> </body> </html>
jsp頁面作好以後,咱們就要寫一個UploadServlet,在編寫上傳servlet時,咱們須要考慮到若是上傳的文件出現重名的狀況,以及上傳的文件可能會出現的亂碼狀況,因此咱們須要編碼與客戶端一致,而且根據文件名的hashcode計算存儲目錄,避免一個文件夾中的文件過多,固然爲了保證服務器的安全,咱們將存放文件的目錄放在用戶直接訪問不到的地方,好比在WEB-INF文件夾下建立一個file文件夾。具體作法以下:css
public class UploadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); System.out.print(request.getRemoteAddr()); boolean isMultipart = ServletFileUpload.isMultipartContent(request); if(!isMultipart){ throw new RuntimeException("請檢查您的表單的enctype屬性,肯定是multipart/form-data"); } DiskFileItemFactory dfif = new DiskFileItemFactory(); ServletFileUpload parser = new ServletFileUpload(dfif); parser.setFileSizeMax(3*1024*1024);//設置單個文件上傳的大小 parser.setSizeMax(6*1024*1024);//多文件上傳時總大小限制 List<FileItem> items = null; try { items = parser.parseRequest(request); }catch(FileUploadBase.FileSizeLimitExceededException e) { out.write("上傳文件超出了3M"); return; }catch(FileUploadBase.SizeLimitExceededException e){ out.write("總文件超出了6M"); return; }catch (FileUploadException e) { e.printStackTrace(); throw new RuntimeException("解析上傳內容失敗,請從新試一下"); } //處理請求內容 if(items!=null){ for(FileItem item:items){ if(item.isFormField()){ processFormField(item); }else{ processUploadField(item); } } } out.write("上傳成功!"); } private void processUploadField(FileItem item) { try { String fileName = item.getName(); //用戶沒有選擇上傳文件時 if(fileName!=null&&!fileName.equals("")){ fileName = UUID.randomUUID().toString()+"_"+FilenameUtils.getName(fileName); //擴展名 String extension = FilenameUtils.getExtension(fileName); //MIME類型 String contentType = item.getContentType(); //分目錄存儲:日期解決 // Date now = new Date(); // DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); // // String childDirectory = df.format(now); //按照文件名的hashCode計算存儲目錄 String childDirectory = makeChildDirectory(getServletContext().getRealPath("/WEB-INF/files/"),fileName); String storeDirectoryPath = getServletContext().getRealPath("/WEB-INF/files/"+childDirectory); File storeDirectory = new File(storeDirectoryPath); if(!storeDirectory.exists()){ storeDirectory.mkdirs(); } System.out.println(fileName); item.write(new File(storeDirectoryPath+File.separator+fileName));//刪除臨時文件 } } catch (Exception e) { throw new RuntimeException("上傳失敗,請重試"); } } //計算存放的子目錄 private String makeChildDirectory(String realPath, String fileName) { int hashCode = fileName.hashCode(); int dir1 = hashCode&0xf;// 取1~4位 int dir2 = (hashCode&0xf0)>>4;//取5~8位 String directory = ""+dir1+File.separator+dir2; File file = new File(realPath,directory); if(!file.exists()) file.mkdirs(); return directory; } private void processFormField(FileItem item) { String fieldName = item.getFieldName();//字段名 String fieldValue; try { fieldValue = item.getString("UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("不支持UTF-8編碼"); } System.out.println(fieldName+"="+fieldValue); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
至此,上傳的任務就基本完成了,有了上傳固然也要有下載功能,在下載以前,咱們須要將全部已經上傳的文件顯示在網頁上,經過一個servlet與一個jsp頁面來顯示,servlet代碼以下:html
public class ShowAllFilesServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String storeDirectory = getServletContext().getRealPath("/WEB-INF/files"); File root = new File(storeDirectory); //用Map保存遞歸的文件名:key:UUID文件名 value:老文件名 Map<String, String> map = new HashMap<String, String>(); treeWalk(root,map); request.setAttribute("map", map); request.getRequestDispatcher("/listFiles.jsp").forward(request, response); } //遞歸,把文件名放到Map中 private void treeWalk(File root, Map<String, String> map) { if(root.isFile()){ String fileName = root.getName();//文件名 String oldFileName = fileName.substring(fileName.indexOf("_")+1); map.put(fileName, oldFileName); }else{ File fs[] = root.listFiles(); for(File file:fs){ treeWalk(file, map); } } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
經過上面的servlet轉發到listFiles.jsp頁面,listFiles.jsp頁面:java
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>title</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1>如下資源可供下載</h1> <c:forEach items="${map}" var="me"> <c:url value="/servlet/DownloadServlet" var="url"> <c:param name="filename" value="${me.key}"></c:param> </c:url> ${me.value} <a href="${url}">下載</a><br/> </c:forEach> </body> </html>
到這裏,文件也顯示出來了,就須要點擊下載進行下載文件了,最後一步,咱們再編寫一個DownloadServlet:web
public class DownloadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uuidfilename = request.getParameter("filename");//get方式提交的 uuidfilename = new String(uuidfilename.getBytes("ISO-8859-1"),"UTF-8");//UUID的文件名 String storeDirectory = getServletContext().getRealPath("/WEB-INF/files"); //獲得存放的子目錄 String childDirecotry = makeChildDirectory(storeDirectory, uuidfilename); //構建輸入流 InputStream in = new FileInputStream(storeDirectory+File.separator+childDirecotry+File.separator+uuidfilename); //下載 String oldfilename = uuidfilename.substring(uuidfilename.indexOf("_")+1); //通知客戶端如下載的方式打開 response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(oldfilename, "UTF-8")); OutputStream out = response.getOutputStream(); int len = -1; byte b[] = new byte[1024]; while((len=in.read(b))!=-1){ out.write(b,0,len); } in.close(); out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } //計算存放的子目錄 private String makeChildDirectory(String realPath, String fileName) { int hashCode = fileName.hashCode(); int dir1 = hashCode&0xf;// 取1~4位 int dir2 = (hashCode&0xf0)>>4;//取5~8位 String directory = ""+dir1+File.separator+dir2; File file = new File(realPath,directory); if(!file.exists()) file.mkdirs(); return directory; } }
文件上傳與下載就已經所有完成了。安全
本文來源於 http://blog.csdn.net/wetsion/article/details/50890031服務器