1. jsphtml
1 <%@ page language="java" contentType="text/html" pageEncoding="utf-8"%> 2 <!DOCTYPE html> 3 <html> 4 <head> 5 <title>文件上傳</title> 6 </head> 7 <body> 8 <form action="FileUploadServlet" method="post" enctype="multipart/form-data"> 9 用戶名:<input type="text" name="name"><br> 10 文件1:<input type="file" name="f1"><br> 11 文件2:<input type="file" name="f2"><br> 12 <input type="submit" value="提交"> 13 </form> 14 15 </body> 16 </html>
2. java java
文件上傳的前提 1.form表單的method必須是post 2.form表單的enctype必須是multipart/form-data 以二進制字節流 進行提交 傳統接收參數的方式無效 DiskFileItemFactory:環境 void setSizeThreshold(int sizeThreshold) 設置緩衝區大小,默認10KB 超出將使用臨時文件上傳 void setRepository(File repository) 設置臨時文件路徑 ServletFileUpload:核心操做類 public void setSizeMax(long sizeMax)設置總文件的大小 public void setFileSizeMax(long fileSizeMax):設置單個文件的大小 public List parseRequest(javax.servlet.http.HttpServletRequest req) 解析請求正文內容 public static boolean isMultipartContent(HttpServletRequest req)//判斷enctype FileItem:輸入域 boolean isFormField():判斷是不是普通字段 String getName():獲取上傳文件名 String getFieldName():獲取普通字段的字段名 String getString():獲取普通字段的值 String getContentType() 得到文件類型 InputStream getInputStream()以流的形式返回上傳文件的主體內容 void delete()刪除臨時文件 文件上傳中須要注意的問題 1.保證安全 上傳文件放在WEB-INF目錄中 2.中文亂碼問題 普通字段亂碼 String fieldValue = item.getString("GBK"); 文件名亂碼 request.setCharacterEncoding("GBK"); 3.重名文件覆蓋 1.UUID 2.使用文件上傳日期分類存儲 3.System.currentMillions() 4.限制文件上傳類型 1.endsWith("")這種方式不可取 2.判斷其mime類型 getContentType() 5.限制用戶上傳文件的大小 1.限制單個上傳文件的大小 upload.setFileSizeMax(4*1024*1024); 2.限制總文件大小 upload.setSizeMax() 6.臨時文件 item.delete(); 7.多個文件上傳時,沒有上傳內容的問題 if(fileName==null||"".equals(fileName.trim())){ continue; } 8.上傳進度檢測 upload.setProgressListener(new ProgressListener(){ 參數一:已上傳的字節數 參數二:總字節數 參數三:第幾項 @Override public void update(long arg0, long arg1, int arg2) { // TODO Auto-generated method stub System.out.println(arg0+" "+arg1+" "+arg2); } });
1 package cn.gs.ly; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.util.List; 9 10 import javax.servlet.ServletException; 11 import javax.servlet.http.HttpServlet; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 15 import org.apache.commons.fileupload.FileItem; 16 import org.apache.commons.fileupload.FileUploadException; 17 import org.apache.commons.fileupload.ProgressListener; 18 import org.apache.commons.fileupload.disk.DiskFileItemFactory; 19 import org.apache.commons.fileupload.servlet.ServletFileUpload; 20 21 22 public class FileUploadServlet extends HttpServlet { 23 @Override 24 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 25 try { 26 //獲得上傳文件的保存目錄。 將上傳的文件存放於WEB-INF目錄下,不容許外界直接訪問,保證上傳文件的安全 27 String realPath = this.getServletContext().getRealPath("/upload");// /WEB-INF/files 28 System.out.println("文件存放位置:"+realPath); 29 //設置臨時目錄。 上傳文件大於緩衝區則先放於臨時目錄中 30 String tempPath = "E:\\tempPath"; 31 System.out.println("臨時文件存放位置:"+tempPath); 32 33 34 //判斷存放上傳文件的目錄是否存在(不存在則建立) 35 File f = new File(realPath); 36 if(!f.exists()&&!f.isDirectory()){ 37 System.out.println("目錄或文件不存在! 建立目標目錄。"); 38 f.mkdir(); 39 } 40 //判斷臨時目錄是否存在(不存在則建立) 41 File f1 = new File(tempPath); 42 if(!f1.isDirectory()){ 43 System.out.println("臨時文件目錄不存在! 建立臨時文件目錄"); 44 f1.mkdir(); 45 } 46 47 /** 48 * 使用Apache文件上傳組件處理文件上傳步驟: 49 * 50 * */ 51 //一、設置環境:建立一個DiskFileItemFactory工廠 52 DiskFileItemFactory factory = new DiskFileItemFactory(); 53 54 //設置上傳文件的臨時目錄 55 factory.setRepository(f1); 56 57 //二、核心操做類:建立一個文件上傳解析器。 58 ServletFileUpload upload = new ServletFileUpload(factory); 59 //解決上傳"文件名"的中文亂碼 60 upload.setHeaderEncoding("UTF-8"); 61 62 //三、判斷enctype:判斷提交上來的數據是不是上傳表單的數據 63 if(!ServletFileUpload.isMultipartContent(req)){ 64 System.out.println("不是上傳文件,終止"); 65 //按照傳統方式獲取數據 66 return; 67 } 68 69 //==獲取輸入項== 70 // //限制單個上傳文件大小(5M) 71 // upload.setFileSizeMax(1024*1024*4); 72 // //限制總上傳文件大小(10M) 73 // upload.setSizeMax(1024*1024*6); 74 75 //四、使用ServletFileUpload解析器解析上傳數據,解析結果返回的是一個List<FileItem>集合,每個FileItem對應一個Form表單的輸入項 76 List<FileItem> items =upload.parseRequest(req); 77 for(FileItem item:items){ 78 //若是fileitem中封裝的是普通輸入項的數據(輸出名、值) 79 if(item.isFormField()){ 80 String filedName = item.getFieldName();//普通輸入項數據的名 81 //解決普通輸入項的數據的中文亂碼問題 82 String filedValue = item.getString("UTF-8");//普通輸入項的值 83 System.out.println("普通字段:"+filedName+"=="+filedValue); 84 }else{ 85 //若是fileitem中封裝的是上傳文件,獲得上傳的文件名稱, 86 String fileName = item.getName();//上傳文件的名 87 //多個文件上傳輸入框有空 的 異常處理 88 if(fileName==null||"".equals(fileName.trim())){ //去空格是否爲空 89 continue;// 爲空,跳過當次循環, 第一個沒輸入則跳過能夠繼續輸入第二個 90 } 91 92 //注意:不一樣的瀏覽器提交的文件名是不同的,有些瀏覽器提交上來的文件名是帶有路徑的,如: c:\a\b\1.txt,而有些只是單純的文件名,如:1.txt 93 //處理上傳文件的文件名的路徑,截取字符串只保留文件名部分。//截取留最後一個"\"以後,+1截取向右移一位("\a.txt"-->"a.txt") 94 fileName = fileName.substring(fileName.lastIndexOf("\\")+1); 95 //拼接上傳路徑。存放路徑+上傳的文件名 96 String filePath = realPath+"\\"+fileName; 97 //構建輸入輸出流 98 InputStream in = item.getInputStream(); //獲取item中的上傳文件的輸入流 99 OutputStream out = new FileOutputStream(filePath); //建立一個文件輸出流 100 101 //建立一個緩衝區 102 byte b[] = new byte[1024]; 103 //判斷輸入流中的數據是否已經讀完的標識 104 int len = -1; 105 //循環將輸入流讀入到緩衝區當中,(len=in.read(buffer))!=-1就表示in裏面還有數據 106 while((len=in.read(b))!=-1){ //沒數據了返回-1 107 //使用FileOutputStream輸出流將緩衝區的數據寫入到指定的目錄(savePath+"\\"+filename)當中 108 out.write(b, 0, len); 109 } 110 //關閉流 111 out.close(); 112 in.close(); 113 //刪除臨時文件 114 try { 115 Thread.sleep(3000); 116 } catch (InterruptedException e) { 117 e.printStackTrace(); 118 } 119 item.delete();//刪除處理文件上傳時生成的臨時文件 120 System.out.println("文件上傳成功"); 121 } 122 } 123 } catch (FileUploadException e) { 124 //e.printStackTrace(); 125 throw new RuntimeException("服務器繁忙,文件上傳失敗"); 126 } 127 } 128 129 @Override 130 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 131 this.doPost(req, resp); 132 }