天天看點

007_Java Web中基于fileupload元件的檔案上傳

input

  • 如果在表單中使用表單元素 ,浏覽器在解析表單時,會自動生成一個輸入框和一個按鈕,輸入框可供使用者填寫本地檔案的檔案名和路徑名,按鈕可以讓浏覽器打開一個檔案選擇框供使用者選擇檔案:
    007_Java Web中基于fileupload元件的檔案上傳

enctype

  • 當表單需要上傳檔案時,需指定表單 enctype 的值為 multipart/form-data
  • 在 form 元素的文法中,enctype 屬性指定将資料發送到伺服器時浏覽器使用的編碼類型。
  • enctype 屬性取值:
    • application/x-www-form-urlencoded:表單 enctype 屬性的預設值。這種編碼方案使用有限的字元集,當使用了非字母和數字時,必須用”%HH”代替(H 代表十六進制數字)。對于大容量的二進制資料或包含非 ASCII 字元的文本來說,這種編碼不能滿足要求。
    • multipart/form-data:form 設定了enctype=“multipart/form-data”屬性後,表示表單以二進制傳輸資料

      accept

accept

  • 表示可以選擇的檔案MIME類型,多個MIME類型用英文逗号分開,常用的MIME類型見下表。
字尾名 MIME名稱
col 3 is right-aligned
col 2 is centered
zebra stripes are neat
*.3gpp audio/3gpp, video/3gpp
*.ac3 audio/ac3
*.asf allpication/vnd.ms-asf
*.au audio/basic
*.css text/css
*.csv text/csv
*.doc application/msword
*.dot application/msword
*.dtd application/xml-dtd
*.dwg image/vnd.dwg
*.dxf image/vnd.dxf
*.gif image/gif
*.htm text/html
*.html text/html
*.jp2 image/jp2
*.jpe image/jpeg
*.jpeg image/jpeg
*.jpg image/jpeg
*.js text/javascript, application/javascript
*.json application/json
*.mp2 audio/mpeg, video/mpeg
*.mp3 audio/mpeg
*.mp4 audio/mp4, video/mp4
*.mpeg video/mpeg
*.mpg video/mpeg
*.mpp application/vnd.ms-project
*.ogg application/ogg, audio/ogg
*.pdf application/pdf
*.png image/png
*.pot application/vnd.ms-powerpoint
*.pps application/vnd.ms-powerpoint
*.ppt application/vnd.ms-powerpoint
*.rtf application/rtf, text/rtf
*.svf image/vnd.svf
*.tif image/tiff
*.tiff image/tiff
*.txt text/plain
*.wdb application/vnd.ms-works
*.wps application/vnd.ms-works
*.xhtml application/xhtml+xml
*.xlc application/vnd.ms-excel
*.xlm application/vnd.ms-excel
*.xls application/vnd.ms-excel
*.xlt application/vnd.ms-excel
*.xlw application/vnd.ms-excel
text/xml, application/xml
*.zip aplication/zip
*.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

multiple

  • multiple:是否可以選擇多個檔案,多個檔案時其value值為第一個檔案的虛拟路徑。

Commons-fileupload 元件

  • Commons-fileupload 元件是 Apache 開源代碼組織用來處理表單檔案上傳的一個子項目,該元件性能優異,可以支援任意大小的檔案的上傳
  • Commons-fileupload 元件從 1.1 版本開始依賴 Apache 的另一個項目:commons-io

Commons-fileupload 元件上傳的基本原理

  • FileUpload元件将頁面送出的所有元素(普通form表單域,如text和檔案域file)都看作一樣的FileItem,這樣上傳頁面送出的 request請求也就是一個FileItem的有序組合,FileUpload元件可以解析該request,并傳回一個一個的FileItem。而對每一個FileItem,FileUpload元件可以判斷出它是普通form表單域還是檔案file域,進而根據不同的類型,采取不同的操作。如果是表單域,就讀出其值,如果是檔案域,就儲存檔案到伺服器硬碟上或者記憶體中。

Commons-fileupload 元件API

  • 在 Commons-fileupload 元件中,主要用到以下三個接口和類:
    007_Java Web中基于fileupload元件的檔案上傳
  • ServletFileUpload 負責處理上傳的檔案資料,并将每部分的資料封裝到 FileItem 對象中。
  • DiskFileItemFactory 是建立 FileItem 對象的工廠,在這個工廠類中可以配置記憶體緩沖區大小和存放臨時檔案的目錄。
  • ServletFileUpload 在接收上傳檔案資料時,會将内容儲存到記憶體緩存區中,如果檔案内容超過了 DiskFileItemFactory 指定的緩沖區的大小,那麼檔案将被儲存到磁盤上,存儲為 DiskFileItemFactory 指定目錄中的臨時檔案。等檔案資料都接收完畢後,ServletUpload 在從檔案中将資料寫入到上傳檔案目錄下的檔案中

測試代碼

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
    </head>

    <body>
        <%--
        基于Apache元件的檔案上傳:
            導入
                commons-fileupload-.jar
                commons-io-.jar
             其它設定與type="file"一緻
             在servlet中使用這兩個jar包進行操作
                .基本思想:
                    .可以解析請求,得到一個FileItem對象組成的List
                    .所有的請求鬥會封裝成一個FileItem對象(文本/檔案/……)
                    .調用FileItem的isFormField()方法,判斷是表單域還是别的(false:表示是一個檔案)
                    .根據類型擷取資訊
                .具體操作
                    .得到List<FileItem>
                        .簡單得到
                            // Create a factory for disk-based file items
                            FileItemFactory factory = new DiskFileItemFactory();

                            // Create a new file upload handler
                            ServletFileUpload upload = new ServletFileUpload(factory);

                            // Parse the request
                            List /* FileItem */ items = upload.parseRequest(request);           

                        .複雜得到(可以設定檔案的一些限制和其它屬性)
                            // Create a factory for disk-based file items
                            DiskFileItemFactory factory = new DiskFileItemFactory();

                            //設定記憶體中最多可以存放的上傳檔案的大小, 若超出則把檔案寫到一個臨時檔案夾中. 以 byte 為機關
                            factory.setSizeThreshold(yourMaxMemorySize);
                            //設定那個臨時檔案夾
                            factory.setRepository(yourTempDirectory);

                            // Create a new file upload handler
                            ServletFileUpload upload = new ServletFileUpload(factory);

                            //設定上傳檔案的總的大小.。也可以設定單個檔案的大小.(setFileSizeMax)
                            upload.setSizeMax(yourMaxRequestSize);

                            // Parse the request
                            List /* FileItem */ items = upload.parseRequest(request);           
                .處理資訊              
        --%>
        <form action="uploadServlet" method="post"  enctype= "multipart/form-data" >
            <!-- type="file":表示是一個使用者檔案上傳的input标簽 -->
            檔案上傳:<input type="file" name="file" />
            <br />
            資訊:<input type="text" name="text" />
            <br />
            <input type="submit" value="送出" />
        </form>     
    </body>
</html>
           
package top.itcourse.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //1.得到List<FileItem>
            //1.1.建立工廠
        DiskFileItemFactory factory = new DiskFileItemFactory();
            //1.2.通過工廠設定JVM處理檔案大小限制(機關是bytes),當超過這個大小的時候,檔案會被寫到臨時目錄下(不然是在記憶體中處理的)
        factory.setSizeThreshold( * );       //500k
            //1.3.設定臨時目錄
        factory.setRepository(new File("/Volumes/Player/FileDire"));

            //1.4.建立ServletFileUpload,把工廠對象傳進去
        ServletFileUpload upload = new ServletFileUpload(factory);
            //1.5.通過ServletFileUpload設定可以上傳的檔案的總大小(機關bytes),差別開DiskFileItemFactory的setSizeThreshold
        upload.setSizeMax( *  * );
            //1.6.獲得List,調用parseRequest方法
        List<FileItem> parseRequest = null;
        OutputStream os = null;
        InputStream is = null;

        try {
            parseRequest  = upload.parseRequest(request);

        //2.周遊所有的FileItem,确認類型
            for (FileItem fileItem : parseRequest) {
                //3.類型為普通表單,列印
                if( fileItem.isFormField() ) {
                    System.out.println("------------------------------------普通表單---------------------------------------");
                    //3.1.擷取普通表單的名字(用的是getFieldName,擷取表單的name)
                    String name = fileItem.getFieldName();
                    //3.2.獲得這個FileItem的值
                    String value = fileItem.getString();
                    System.out.println(name + " : " + new String(value.getBytes("iso-8859-1"),"utf-8"));
                    System.out.println("---------------------------------------------------------------------------");
                //4.類型為檔案類型(非普通表單),儲存在指定位置
                } else {
                    System.out.println("------------------------------------檔案---------------------------------------");
                    //input中的name
                    String fieldName = fileItem.getFieldName();
                    //檔案名
                    String fileName = fileItem.getName();
                    //
                    String contentType = fileItem.getContentType();
                    //檔案大小,機關bytes
                    long sizeBytes = fileItem.getSize();
                    System.out.println("fieldName : " + fieldName);
                    System.out.println("fileName : " + fileName);
                    System.out.println("contentType : " + contentType);

                    //擷取檔案流,存在相應的目錄下
                    is = fileItem.getInputStream();
                    byte[] bytes = new byte[];
                    int pos;

                    os = new FileOutputStream(new File("/Volumes/Player/FileDire/Download/" + fileName));
                    while( (pos = is.read(bytes)) != - ) {
                        os.write(bytes, , pos);
                    }
                    System.out.println("檔案上傳完畢~~");
                    System.out.println("---------------------------------------------------------------------------");
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        } finally {
            if( os != null ) {
                os.close();
            }

            if( is != null ) {
                is.close();
            }
        }
    }
}
           

效果及完整源碼下載下傳

效果及完整源碼下載下傳:點選這裡

歡迎加入QQ交流群:451826376

007_Java Web中基于fileupload元件的檔案上傳