Java文件上傳:common-fileupload上傳組件

參考轉載:

https://www.cnblogs.com/longqingyang/p/5579889.html

原理:

common-fileupload組件利用DiskFileItemFactory工廠方法生成request的表單內容解析器,將表單內容解析成List<FileItem>,然後循環獲取處理上傳文件的輸入流getInputStream()。

該組件依賴commons-io組件。

步驟:

1、檢查保存目錄以及臨時文件保存目錄

2、判斷提交上來的數據是否是上傳表單的數據,即是否是enctype="multipart/form-data"

3、創建DiskFileItemFactory工廠

4、利用工廠創建ServletFileUpload文件上傳解析器

5、使用ServletFileUpload解析器解析上傳數據,解析結果返回的是List<FileItem>集合,FileItem對應Form表單的輸入項

6、循環處理每一個FileItem

7、如果是普通表單輸入項,獲取表單字段和表單內容

8、如果是文件上傳項,獲取處理文件名,並getInputStream(),然後保存到保存目錄中

代碼:

fileupload,jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>fileupload test</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/servlet/uploadHandleServlet" method="post" enctype="multipart/form-data">
        上傳用戶:<input type="text" name="username"><br>
        上傳文件1:<input type="file" name="file1"><br>
        上傳文件2:<input type="file" name="file2"><br>
        <input type="submit" value="submit">
    </form>
</body>
</html>
uploadHandleServlet.Java
package servlet;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import sun.swing.FilePane;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.List;
import java.util.UUID;

public class uploadHandleServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File saveFile = new File(savePath);
        if (!saveFile.exists() && !saveFile.isDirectory()) {
            System.out.println("目錄或者文件不存在");
            saveFile.mkdir();
        }
        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
        File tempFile = new File(tempPath);
        if (!tempFile.exists() && !tempFile.isDirectory()) {
            System.out.println("目錄或者文件不存在");
            tempFile.mkdir();
        }
        //消息提示
        String message = "";
        try {
            //使用fileupload上傳文件
            //1、判斷是否爲多媒體多部件上傳,enctype=multipart/form-data
            if (!ServletFileUpload.isMultipartContent(request)) {
                PrintWriter writer = response.getWriter();
                writer.println("Error: 表單必須寫有:enctype=multipart/form-data");
                writer.flush();
                return;
            }
            
            //2、創建一個創建一個DiskFileItemFactory工廠
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            diskFileItemFactory.setSizeThreshold(1024 * 10);//設置工廠的緩衝區的大小,當上傳的文件大小超過緩衝區的大小時,就會生成一個臨時文件存放到指定的臨時目錄當中。
            diskFileItemFactory.setRepository(tempFile);//設置上傳時生成的臨時文件的保存目錄
            
            //3、利用工廠創建文件上傳解析器
            ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
            servletFileUpload.setHeaderEncoding("UTF-8");//解決上傳文件名的中文亂碼
            servletFileUpload.setProgressListener(new ProgressListener() {
                @Override
                public void update(long pBytesRead, long pContentLength, int i) {
                    System.out.println("文件大小爲:" + pContentLength + ",當前已處理:" + pBytesRead);
                }
            });
            servletFileUpload.setFileSizeMax(1024 * 1024);//設置上傳單個文件的大小的最大值
            servletFileUpload.setSizeMax(1024 * 1024 * 10);//設置上傳文件總量的最大值,最大值=同時上傳的多個文件的大小的最大值的和
            
            //4、使用ServletFileUpload解析器解析上傳數據,解析結果返回的是一個List<FileItem>集合,每一個FileItem對應一個Form表單的輸入項
            List<FileItem> fileItemList = servletFileUpload.parseRequest(request);
            for (FileItem item : fileItemList) {
                //如果fileitem中封裝的是普通輸入項的數據
                if (item.isFormField()) {
                    String name = item.getFieldName();
                    String value = item.getString("UTF-8");//解決普通輸入項的數據的中文亂碼問題
                    System.out.println(name + "  " + value);
                } else {
                    String fileName = item.getName();//如果fileitem中封裝的是上傳文件,得到上傳的文件名稱
                    System.out.println("文件名稱:" + fileName);
                    if (fileName == null || fileName.trim().equals("")) {
                        continue;
                    }
                    fileName = fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1);//ie瀏覽器可能帶路徑
                    String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1);
                    if ("zip".equals(fileExtName) || "rar".equals(fileExtName) || "tar".equals(fileExtName) || "jar".equals(fileExtName)) {
                        request.setAttribute("message", "上傳文件類型不符合");
                        request.getRequestDispatcher("/fileupload/message.jsp").forward(request, response);
                        return;
                    }
                    System.out.println("上傳文件的擴展名:" + fileExtName);
                    fileName = UUID.randomUUID().toString() + "_" + fileName;
                    System.out.println("保存路徑爲:" + savePath);

//                    普通IO方式讀取
//                    InputStream is = item.getInputStream();
//                    FileOutputStream fos=new FileOutputStream(savePath+File.separator+fileName);
//                    byte[] buffer = new byte[1024];
//                    int length=0;
//                    while ((length = is.read(buffer)) > 0) {
//                        fos.write(buffer,0,length);
//                    }

                    //NIO方式讀取
                    InputStream is = item.getInputStream();
                    ReadableByteChannel readChannel = Channels.newChannel(is);
                    FileOutputStream fos = new FileOutputStream(savePath + File.separator + fileName);
                    WritableByteChannel writeChannel = Channels.newChannel(fos);
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int length = 0;
                    while ((length = readChannel.read(buffer)) > 0) {
                        buffer.flip();
                        writeChannel.write(buffer);
                        buffer.clear();
                    }

                    is.close();
                    fos.close();
                    item.delete();
                    message = "文件上傳成功";
                }
            }

        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("message", "單個文件超出最大值");
            request.getRequestDispatcher("/fileupload/message.jsp").forward(request, response);
            return;
        } catch (FileUploadBase.SizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("message", "上傳文件的總的大小超出限制的最大值!!!");
            request.getRequestDispatcher("/fileupload/message.jsp").forward(request, response);
            return;
        } catch (FileUploadException e) {
            e.printStackTrace();
            message = "文件上傳失敗";
        } catch (Exception e) {
            e.printStackTrace();
            message = e.getMessage();
        }
        request.setAttribute("message", message);
        request.getRequestDispatcher("/fileupload/message.jsp").forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

message.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${requestScope.message}
</body>
</html>

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章