檔案上傳(Java web)
阿新 • • 發佈:2022-03-29
檔案上傳要求:
- 提供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) throwsServletException, 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>