1. 程式人生 > 其它 >檔案上傳(Java web)

檔案上傳(Java web)

檔案上傳要求:

  • 提供form表單,表單的提交方式必須是post
  • form表單中的enctype屬性必須是multipart/form-data
  • 表單中提供input type=”file”上傳輸入域。

一.  利用HttpServletRequest 的 getPart()方法進行檔案上傳。

   Servlet3.0(及以上版本) 提供了專門的檔案上傳 API。 HttpServletRequest 的 getPart()方法可以完成單個檔案上傳,而 getParts()方法可以完成多個檔案上傳。

1.編寫servlet。

@WebServlet(name = "ServletUpload", value = "/ServletUpload")
@MultipartConfig
//表示當前 Servlet 可以處理 Multipart 請求,注意必須新增這個註解 public class ServletUpload extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException { //1.設定儲存路徑 String realPath = this.getServletContext().getRealPath("/save"); File file = new File(realPath); if (!file.exists()){//不存在則建立檔案 file.mkdir(); } //2.獲取上傳檔案,photo是html表單中的name Part photo = request.getPart("photo");
//3.獲取上傳檔案的名字 String name = photo.getSubmittedFileName(); //3.1獲取字首 String subIndex = name.substring(0, name.lastIndexOf(".")); //3.2獲取字尾 String subLast=name.substring(name.lastIndexOf("."));//.xxx //4.將上傳的檔案寫入到指定的伺服器路徑中 //UUID.randomUUID()避免檔名重複 photo.write(realPath+"/"+ subIndex+ UUID.randomUUID()+subLast); } }

2.編寫jsp。

<form action="${pageContext.request.contextPath}/ServletUpload" method="post" enctype="multipart/form-data">
    <p>上傳使用者:<label>
        <input type="text" name="username">
    </label></p>
    <p><input type="file" name="photo"></p>
    <p>
        <input type="submit">|<input type="reset">
    </p>
</form>

3.測試結果。

二.利用FileUpload工具進行檔案上傳。

1.匯入相關依賴

<!-- 匯入commons-fileupload依賴-->
<dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
</dependency>

  只用匯入此依賴,低版本可能還需要匯入commons-io依賴。

2.在WEB-INF下建立lib目錄,匯入Commons-fileupload和commons-io兩個jar包。

 3.編寫servlet。

 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        if (!ServletFileUpload.isMultipartContent(req)) { //不包含檔案上傳控制元件,即普通表單
            return;
        }
        //建立上傳檔案的儲存路徑:外界無法直接訪問
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        makeDirIfNotExist(uploadFile);
        // 建立臨時檔案的儲存路徑
        String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
        File tmpFile = new File(tmpPath);
        makeDirIfNotExist(tmpFile);

        // 1、建立DiskFileItemFactory物件
        DiskFileItemFactory factory = getDiskFileItemFactory(tmpFile);
        // 2、建立ServletFileUpload物件
        ServletFileUpload servletFileUpload = getServletFileUpload(factory);
        // 3、解析請求並處理檔案傳輸
        String msg = "";
        try {
            msg = uploadParseRequest(req, servletFileUpload, uploadPath);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }

        req.setAttribute("msg", msg);
        try {
            req.getRequestDispatcher("/success.jsp").forward(req, resp);
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }

    private String uploadParseRequest(HttpServletRequest httpServletRequest, ServletFileUpload servletFileUpload, String uploadPath)
            throws FileUploadException, IOException {
        String msg = "";

        // 解析前端請求,將每個表單項解析並封裝成FileItem物件
        List<FileItem> fileItems = servletFileUpload.parseRequest(httpServletRequest);
        for (FileItem fileItem : fileItems) {
            // 判斷表單項是否為上傳檔案
            if (fileItem.isFormField()) { // 普通文字
                String filedName = fileItem.getFieldName(); // 獲取欄位名:表單項name屬性的值
                String value = fileItem.getString("UTF-8"); // FileItem物件中儲存的資料流內容:即表單項為普通文字的輸入值
                System.out.println(filedName + ":" + value);
            } else { // 上傳檔案
                //處理檔案
                String uploadFileName = fileItem.getName();// 上傳檔名
                System.out.println("上傳的檔名:" + uploadFileName);

                if (uploadFileName == null || uploadFileName.trim().equals("")) { // 檔名為空值或空
                    continue; // 進入下一輪迴圈,判斷下一個FileItem物件
                }
                String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); // 檔案字尾名
                System.out.println(uploadFileName + ":" + fileExtName");
                // 使用UUID保證檔名唯一
                String uuidPath = UUID.randomUUID().toString();
                // 儲存路徑:uploadPath
                String realPath = uploadPath + '/' + uuidPath; // 真實存在的路徑
                // 給每個檔案建立一個資料夾
                File realPathFile = new File(realPath);
                makeDirIfNotExist(realPathFile);
                // 獲得輸入流
                InputStream is = fileItem.getInputStream();
                // 獲得輸出流
                FileOutputStream fos = new FileOutputStream(realPathFile + "/" + uploadFileName);
                // 建立緩衝區
                byte[] buffer = new byte[1024];
                int len;
                while ((len = is.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                msg = "檔案上傳成功!";
                fileItem.delete(); // 上傳成功,清除臨時檔案
                fos.close();
                is.close();
            }
        }

        return msg;
    }

    private ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
        // ServletFileUpload servletFileUpload = new ServletFileUpload(factory); // 構造方法設定FileItemFactory
        ServletFileUpload servletFileUpload = new ServletFileUpload();
        servletFileUpload.setFileItemFactory(factory); // 設定FileItemFactory
        // 監聽檔案上傳進度
        servletFileUpload.setProgressListener(new ProgressListener() {
            @Override
            public void update(long pBytesRead, long pContentLength, int pItems) {
                String percentage = (int) (((double) pBytesRead / pContentLength) * 100) + "%";
                System.out.println("總大小:" + pContentLength + ",已上傳:" + pBytesRead + "\t" + percentage);
            }
        });
        // 處理亂碼問題
        servletFileUpload.setHeaderEncoding("UTF-8");
        // 設定單個上傳檔案的最大值
        servletFileUpload.setFileSizeMax(1024 * 1024 * 10); // 10MB
        // 設定總共上傳檔案的最大值
        servletFileUpload.setSizeMax(1024 * 1024 * 10); // 10MB

        return servletFileUpload;
    }

    private DiskFileItemFactory getDiskFileItemFactory(File tmpFile) {
        // return new DiskFileItemFactory(1024 * 1024, tmpFile);

        DiskFileItemFactory factory = new DiskFileItemFactory();
        factory.setSizeThreshold(1024 * 1024); //大於1MB時fileupload元件將使用臨時檔案快取上傳檔案
        factory.setRepository(tmpFile); // 臨時資料夾
        return factory;
    }
    private void makeDirIfNotExist(File file) {//檔案不存在則建立
        if (!file.exists()) {
            file.mkdir();
        }
    }

4.編寫jsp。

<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
  <p>上傳使用者:<label>
    上傳使用者:
    <input type="text" name="username">
  </label></p>
  <p><input type="file" name="file"></p>
  <p>
    <input type="submit">|<input type="reset">
  </p>
</form>

5.測試結果。