javaweb上传文件
目錄
1.簡述
2.原理講解
3.代碼如下(含注釋)
3.1獲得DiskFileItemFactory對象
3.2獲得ServletFileUpload對象?
?3.3上傳文件?
3.4 doPost()
4.運(yùn)行結(jié)果
1.簡述
在一個web項目中,用戶向工程中上傳文件是十分常見的操作,如頭像設(shè)置、背景圖片設(shè)置等。服務(wù)器在保存用戶上傳的文件的時候,需要解決以下四個問題:1.用戶上傳的文件不能直接通過在地址欄輸入url去訪問;2.用戶上傳的文件不能被覆蓋(在同一個文件夾下的同名文件會被覆蓋);3.限制上傳文件的最大值;4.可以限制上傳文件的類型,在收到上傳文件名時,判斷后綴名是否合法。
這篇文章將簡單講解如何在Javaweb項目上傳文件并解決上面提到的四個問題
2.原理講解
上傳文件的表單如圖所示
一般在處理上傳文件的時候,用流來處理,但是這樣的話需要自己實(shí)現(xiàn)網(wǎng)絡(luò)通信底層,太麻煩了,這里使用apache的commons-io組件來完成。
ServletFileUpload類負(fù)責(zé)處理上傳的文件數(shù)據(jù),并將表單中的每個輸入項封裝成FileItem對象。在獲取ServletFileUpload對象的時候,需要一個DiskFileItemFactory對象
通過ServletFileUpload對象獲得FileItem對象后,遍歷所有的FileItem對象,判斷每個對象只是簡單的表單元素還是包含了文件,若包含了文件,將文件進(jìn)行處理保存,并轉(zhuǎn)發(fā)到上傳信息的頁面就好了。
為了避免用戶通過輸入url地址直接訪問到服務(wù)器上的文件,可以設(shè)置攔截器,這里就直接把文件存儲在WEB-INF目錄下了。為了防止文件覆蓋,項目中使用了UUID這個類來獲得一個唯一的標(biāo)識符,利用這個唯一的標(biāo)識符來存儲文件就不會發(fā)生覆蓋的情況了。
3.代碼如下(含注釋)
3.1獲得DiskFileItemFactory對象
public DiskFileItemFactory getDiskFileItemFactory(File tempFile){DiskFileItemFactory factory = new DiskFileItemFactory(); // 為上傳文件設(shè)置一個大小限定,當(dāng)文件超過這個大小的時候,緩存在暫存區(qū)factory.setSizeThreshold(1024*1024); //大小為1Mfactory.setRepository(tempFile); //設(shè)置暫存區(qū)return factory;}3.2獲得ServletFileUpload對象?
public ServletFileUpload getServletFileUpload(DiskFileItemFactory factory){ServletFileUpload upload = new ServletFileUpload(factory);upload.setProgressListener(new ProgressListener() {@Override // pBytesRead:已經(jīng)讀取的文件大小 // pContentLength:文件總大小public void update(long pBytesRead, long pContentLength, int pItems) {System.out.println("總大小:"+ pContentLength + ";已上傳:" + pBytesRead);}}); // 處理亂碼問題upload.setHeaderEncoding("UTF-8"); // 設(shè)置單個文件的最大值upload.setFileSizeMax(1024*1024*10); // 設(shè)置總共能夠上傳文件的大小upload.setSizeMax(1024*1024*10);return upload;}?3.3上傳文件?
public void uploadFile(HttpServletRequest req, HttpServletResponse resp,ServletFileUpload upload, String uploadPath) throws IOException, ServletException {String msg = "文件上傳失敗";// 把前端請求解析,封裝成一個FileItem對象,從ServletFIleUpload對象中獲取List<FileItem> fileItems = null;try {fileItems = upload.parseRequest(req);} catch (FileUploadException e) {e.printStackTrace();}for (FileItem fileItem : fileItems) { // 當(dāng)前FileItem對象只是一個表單對象if(fileItem.isFormField()){String name = fileItem.getFieldName(); //獲得表單控件的name值String value = fileItem.getString("UTF-8");//獲得文本,處理亂碼System.out.println(name+" :"+value);}else { // 當(dāng)前FileItem包含文件 // ===========================處理文件===============================String uploadFileName = fileItem.getName();if(uploadFileName.trim().equals("") || uploadFileName==null){continue;}// 獲得上傳的文件名String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/")+1); // 獲得上傳的文件后綴String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);// 使用UUID獲得一個唯一的識別通用碼,保證文件名唯一 // 網(wǎng)絡(luò)傳輸中的東西,都需要序列化 // 實(shí)體類如果想要在多個電腦上運(yùn)行,需要進(jìn)行傳輸===》使用序列號String uuidPath = UUID.randomUUID().toString();// ==========================存放地址==========================================String readPath = uploadPath+"/"+uuidPath; // 給每個文件創(chuàng)建也給對應(yīng)的文件夾File realPathFile = new File(readPath);if(!realPathFile.exists()){realPathFile.mkdir();}// ===========================文件傳輸========================================== // 獲得文件上傳的流InputStream inputStream = fileItem.getInputStream(); // 創(chuàng)建一個文件輸出流FileOutputStream fos = new FileOutputStream(readPath+"/"+fileName); // 創(chuàng)建一個緩沖區(qū)byte[] buffer = new byte[1024*1024]; // 判斷是否讀取完畢int len = 0;while ((len=inputStream.read(buffer))>0){fos.write(buffer, 0, len);} // 關(guān)閉流fos.close();inputStream.close();}msg = "文件上傳成功";}req.setAttribute("msg", msg);req.getRequestDispatcher("info.jsp").forward(req, resp);}3.4 doPost()
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 判斷上傳的文件是普通表單還是帶文件的表單String msg = "文件上傳失敗";if(!ServletFileUpload.isMultipartContent(req)){return;}// 創(chuàng)建上傳文件的保存路徑,建議放在web-inf路徑下以保證安全,用戶無法直接訪問上傳的文件String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");File uploadFile = new File(uploadPath);if(!uploadFile.exists()){//如果文件夾不存在,則創(chuàng)建改文件夾uploadFile.mkdir();}// 緩存臨時文件 // 臨時路徑,如果文件超過了預(yù)期大小,就放到臨時文件夾下String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");File tmpFile = new File(tmpPath);if(!tmpFile.exists()){tmpFile.mkdir();}// 處理上傳的文件,一般需要通過流來獲取 // 此處使用apache的組件來實(shí)現(xiàn) commons-io/** ServletFileUpload負(fù)責(zé)處理上傳的文件數(shù)據(jù),并將表單中的每個輸入項封裝成fileItem對象* 在使用ServletFileUpload對象解析請求時需要DIskFileItemFactory對象* 所有,需要在進(jìn)行解析工作前構(gòu)造好DiskFileItemFactory對象*/// 1. 創(chuàng)建DiskFileIntemFactory對象,處理文件上傳路徑或者大小限制DiskFileItemFactory factory = getDiskFileItemFactory(tmpFile);// 2。獲取ServletFileUploadServletFileUpload upload = getServletFileUpload(factory);// 3.處理上傳文件uploadFile(req, resp,upload, uploadPath);}補(bǔ)充:通過表單上傳文件,get方法對上傳文件的大小有限制,post方法沒有限制,所以一般使用post方法。而且使用get方法的話在獲取ServletFileUpload時會出錯。另外,表單如果包含一個文件上傳輸入的話,這個表單的enctype屬性就必須設(shè)置為multipart/form-data。
4.運(yùn)行結(jié)果
通過表單提交了文件后,可以在tomcat目錄下找到項目文件夾,在WEB-INF目錄下就多出了upload和temp這兩個文件夾,上傳的文件都保存在這兩個文件夾下面。
總結(jié)
以上是生活随笔為你收集整理的javaweb上传文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python拼图游戏_Python加py
- 下一篇: 光学遥感基础总结