1. 程式人生 > 其它 >Javaweb檔案上傳——詳細可見Java I/O

Javaweb檔案上傳——詳細可見Java I/O

檔案上傳的前端必要引數

get方法上傳檔案有大小限制,post無限制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <form action="${pageContext.request.contextPath }/upload.do" enctype="multipart/form-data" method="post" >
    上傳使用者:<input type="text" name="username"><br/>
    <input type="file" name="file1"><br/>
    <input type="file" name="file2">
    <input type="submit"> | <input type="reset">
  </form>
  </body>
</html>

檔案上傳請求處理

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("進入servlet...............");
        FileMothed fileMothed = new FileMothed();
        //判斷上傳表單是普通型別還是帶檔案的表單
        if (!ServletFileUpload.isMultipartContent(request)) {
            return;//終止執行
        }

        //建立上傳檔案的儲存路徑,建議放在WEB-INF下,安全,使用者無法直接訪問上傳的檔案
        String realPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(realPath);
        if (!uploadFile.exists()) {
            uploadFile.mkdir();//建立這個目錄
        }
        //快取,臨時檔案
        //臨時檔案,加入檔案超過了預期的大小,我們就把它放到一個臨時檔案中,過幾天自動刪除,或提醒使用者轉存為永久
        String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
        File file = new File(tmpPath);
        if (!file.exists()){
            file.mkdir();//建立這個臨時資料夾
        }
        //處理上傳的檔案,一般都需要通過流來獲取,我可以通過request.getInputStream();原生太的檔案上傳流獲取,但十分麻煩
        //建議使用Apache的檔案上傳元件來實現,common-fileupload它需要依賴於commons-io元件
        //1.建立DiskFileItemFactory物件,處理檔案上傳的路徑或者大小限制(可以封裝為單獨的方法)
        DiskFileItemFactory factory = fileMothed.getDiskFileItemFactory(file);
        /*ServletFileUpload負責處理上傳的檔案資料,並將表單中每個輸入項封裝成一個FileItem物件,
        在使用ServletFileUpload物件解析請求時需要DiskFileItemFactory物件
        所以,我們需要在進行解析工作之前構造好DiskFileItemFactory物件
        通過ServletFileUpload物件的構造方法或setFileItemFactory()方法設定ServletFileUpload物件的fileItemFactory屬性
        * */
        //2.獲取ServletFileUpload
        ServletFileUpload fileUpload = fileMothed.getServletFileUpload(factory);

        //3.處理上傳檔案
        String msg = null;
        try {
            msg = fileMothed.uploadFile(request, realPath, fileUpload);
            //轉發
            request.setAttribute("msg", msg);
            request.getRequestDispatcher("/info.jsp").forward(request, response);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

檔案上傳方法體

public class FileMothed{

    public static DiskFileItemFactory getDiskFileItemFactory(File file){
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //通過該工廠設定一個緩衝區大小,當檔案上傳的大小超過這個緩衝區的時候,將其放入到臨時檔案目錄下
        factory.setSizeThreshold(1024*1024);//快取大小1M
        factory.setRepository(file);//零食檔案 的儲存目錄,需要傳入一個File
        return factory;
    }

    public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory){
        ServletFileUpload upload = new ServletFileUpload(factory);
        //監聽檔案上傳進度、
        upload.setProgressListener(new ProgressListener() {
            @Override
            public void update(long pBytesRead, long pContentLength, int i) {
                //pBytesRead:已經讀取到的檔案大小
                //pContentLength:檔案大小
                System.out.println("總大小:"+pContentLength+"已上傳:"+pBytesRead);
            }

        });
        //處理亂碼問題
        upload.setHeaderEncoding("UTF-8");
        //設定單個檔案的最大值
        upload.setFileSizeMax(1024*1024*10);
        //設定總共能夠上傳檔案的大小
        //1024=1kb*1024=1M*10=10M
        upload.setSizeMax(1024*1024*100);

        return upload;
    }

    public String uploadFile(HttpServletRequest request, String uploadPath, ServletFileUpload upload) throws IOException, FileUploadException {
        String msg = "";
        //把前端請求解析,封裝成一個FileItem物件,需要從ServletFileUpload物件中獲取
        //ServletFileUpload負責處理上傳的檔案資料,並將表單中每個輸入項封裝成一個FileItem物件
        try {
            List<FileItem> fileItems = upload.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()) {//如果是普通的輸入表單
                    String fieldName = fileItem.getFieldName();
                    //處理亂碼
                    String value = fileItem.getString("UTF-8");
                    System.out.println(fieldName + ":" + value);
                } else {//檔案情況下
                    //檔案
                    //===========處理檔案============
                    String uploadFileName = fileItem.getName();
                    System.out.println("uploadFileName:" + uploadFileName);
                    //可能存在檔名不合法的情況
                    //去掉首尾空格
                    if (uploadFileName == null || "".equals(uploadFileName.trim())) {
                        continue;
                    }
                    //獲取上傳的檔名
                    String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                    //獲取檔案的字尾名
                    String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
                    //如果檔案字尾名fileExtName不是我們所需要的,就直接return,不處理,告訴使用者檔案型別不對

                    //可以使用UUID(統一識別的通用碼),保證檔名唯一
                    //UUID.randomUUID() 隨機生一個唯一識別的通用碼
                    //網路從傳輸中的東西,都需要序列化
                    //implements java.io.Serializable 標記介面  JVM本地方法棧--呼叫》C++
                    String uuidPath = UUID.randomUUID().toString();

                    //===========存放地址============
                    String realPath = uploadPath + "/" + uuidPath;
                    File realPathFile = new File(realPath);
                    if (!realPathFile.exists()) {
                        realPathFile.mkdir();
                    }
                    //===========檔案傳輸============
                    InputStream inputStream = fileItem.getInputStream();
                    FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
                    byte[] buffer = new byte[1024 * 1024];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    fos.close();
                    inputStream.close();
                    msg = "上傳成功~";
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
            msg = "上傳失敗~";
        }
        return msg;
    }
}