JavaWeb實現(xiàn)上傳文件功能
本文實例為大家分享了JavaWeb實現(xiàn)上傳文件的具體代碼,供大家參考,具體內(nèi)容如下
這是需要使用到的兩個jar包一定要導(dǎo)入到lib目錄中,并添加到發(fā)布的lib目錄下
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> ? <head> ? ? <title>$Title$</title> ? </head> ? <body> ? <a href="upload.jsp" rel="external nofollow" >點擊上傳文件</a> ? </body> </html>
upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> ? ? <title>上傳文件頁面</title> </head> <body> <form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post"> ? ? <p>請輸入用戶: <input type="text" name="username"></p> ? ? <p>上傳文件: <input type="file" name="file"></p> ? ? <p><input type="submit"></p> </form> </body> </html>
UpLoadServlet
package com.pzy.servlet; import org.apache.commons.fileupload.FileItem; 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 javax.servlet.http.HttpServletRequest; import java.io.*; import java.util.List; import java.util.UUID; public class UpLoadServlet extends javax.servlet.http.HttpServlet { ? ? protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { ? ? ? ? doGet(request,response); ? ? } ? ? protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { ? ? ? ? try { ? ? ? ? //先判斷提交的是普通請求還是帶有文件的請求 ? ? ? ? if(!ServletFileUpload.isMultipartContent(request)){ ? ? ? ? ? ? return;//如果是普通文件,直接返回 ? ? ? ? }//如果通過了這個if,那說明表單是帶有文件的 ? ? ? ? //創(chuàng)建上傳文件的保存路徑,建議在WEB-INF下,因為這個文件夾是安全的,用戶是無法訪問這個文件夾的 ? ? ? ? String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload"); ? ? ? ? File uploadFile = new File(uploadPath); ? ? ? ? //判斷這個文件夾是否存在 ? ? ? ? if(!uploadFile.exists()){ ? ? ? ? ? ? uploadFile.mkdir(); ? ? ? ? } ? ? ? ? //創(chuàng)建一個臨時路徑, 假如文件超過了預(yù)期的大小,我們就把他放在一個臨時文件下,過幾天自動刪除,或者提醒用戶轉(zhuǎn)存為永久 ? ? ? ? String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp"); ? ? ? ? File file = new File(tmpPath); ? ? ? ? //判斷文件夾是否存在 ? ? ? ? if(!file.exists()){ ? ? ? ? ? ? file.mkdir();//沒有的話就創(chuàng)建一個這樣的目錄 ? ? ? ? } ? ? ? ? /*處理上傳的文件,一般都需要通過流來獲取,我們可以使用request.getInputStream(),原生態(tài)的文件上傳流獲取,十分麻煩 ? ? ? ? *我們建議使用Apache的文件上傳組件來實現(xiàn),commons-fileupload,它需要依賴于common-io ? ? ? ? */ ? ? ? ? //1.創(chuàng)建DiskFileItemFactory對象,處理文件上傳路徑和大小限制的; ? ? ? ? DiskFileItemFactory factory=getDiskFileItemFactory(file); ? ? ? ? //2.獲取ServletFileUpLoad ? ? ? ? ServletFileUpload upload=getServletFileUpLoad(factory); ? ? ? ? //3.處理上傳的文件 ? ? ? ? String msg=uploadParseRequest(upload,request,uploadPath); ? ? ? ? //servlet請求轉(zhuǎn)發(fā)消息 ? ? ? ? request.setAttribute("msg",msg); ? ? ? ? request.getRequestDispatcher("msg.jsp").forward(request,response); ? ? ? ? } catch (FileUploadException e) { ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? } ? ? } ? ? public static ?DiskFileItemFactory getDiskFileItemFactory(File file) { ? ? ? ? DiskFileItemFactory factory = new DiskFileItemFactory(); ? ? ? ? //通過這個工廠設(shè)置一個緩沖區(qū),當(dāng)上傳的文件大于這個緩沖區(qū)的時候,將他放入臨時文件中 ? ? ? ? factory.setSizeThreshold(1024*1024);//此時設(shè)置緩沖區(qū)大小為1M ? ? ? ? factory.setRepository(file);//臨時目錄的保存目錄,需要一個file ? ? ? ? return factory; ? ? } ? ? public static ServletFileUpload getServletFileUpLoad(DiskFileItemFactory factory) { ? ? ? ? ServletFileUpload upload = new ServletFileUpload(factory); ? ? ? ? //監(jiān)聽文件上傳進度 ? ? ? ? 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);//最大值為10m ? ? ? ? //設(shè)置總共文件能夠上傳的文件大小 ? ? ? ? upload.setSizeMax(1024*1024*10); ? ? ? ? return upload; ? ? } ? ? public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath) throws FileUploadException, IOException { ? ? ? ?String msg=""; ? ? ? ? //把前端請求進行解析,封裝成一個FileItem對象 ? ? ? ? List<FileItem> fileItems = upload.parseRequest(request); ? ? ? ? for(FileItem fileItem:fileItems){ ? ? ? ? ? ? if(fileItem.isFormField()){//判斷上傳的文件是普通的表單還是帶文件的表單 ? ? ? ? ? ? ? ? //getFieldName指的是前端表單控件的name; ? ? ? ? ? ? ? ? String name = fileItem.getFieldName(); ? ? ? ? ? ? ? ? String value = fileItem.getString("UTF-8");//處理亂碼 ? ? ? ? ? ? ? ? System.out.println(name+":"+value); ? ? ? ? ? ? }else{//判斷它是上傳的文件 ? ? ? ? ? ? ? ? //============================================處理文件================================= ? ? ? ? ? ? ? ? //拿到文件的名字 ? ? ? ? ? ? ? ? String uploadFileName = fileItem.getName(); ? ? ? ? ? ? ? ? System.out.println("上傳的文件名是:"+uploadFileName); ? ? ? ? ? ? ? ? if(uploadFileName.trim().equals("")||uploadFileName==null){ ? ? ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? //獲得上傳的文件名 ? ?(一般進來的文件都會包含目錄.例如/image/girl/pop.png) ? ? ? ? ? ? ? ? String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1); ? ? ? ? ? ? ? ? //獲得后綴 ? ? ? ? ? ? ? ? String fileExtName=uploadFileName.substring(uploadFileName.lastIndexOf(".")+1); ? ? ? ? ? ? ? ? /* ? ? ? ? ? ? ? ? 如果文件后綴名fileExtName不是我們需要的就直接return,不處理,告訴用戶文件類型不對 ? ? ? ? ? ? ? ? ?*/ ? ? ? ? ? ? ? ? System.out.println("文件信息名:"+fileName+"----文件類型"+fileExtName); ? ? ? ? ? ? ? ? //可以使用UUID(唯一識別的通用碼),保證文件名的唯一; ? ? ? ? ? ? ? ? //UUID.randomUUID(),隨機生成一個唯一識別的通用碼; ? ? ? ? ? ? ? ? String uuidPath = UUID.randomUUID().toString(); ? ? ? ? ? ? ? ? //==========================文件處理完畢===================================== ? ? ? ? ? ? ? ? //存到哪? ? ? ?uploadPath ? ? ? ? ? ? ? ? //文件的真實存在路徑 ? ? realPath ? ? ? ? ? ? ? ? String realPath=uploadPath+"/"+uuidPath; ? ? ? ? ? ? ? ? //給每個文件創(chuàng)建一個對應(yīng)的文件夾 ? ? ? ? ? ? ? ? File realPathFile = new File(realPath); ? ? ? ? ? ? ? ? if(!realPathFile.exists()){ ? ? ? ? ? ? ? ? ? ? realPathFile.mkdir(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? //=================================存放地址完畢======================================== ? ? ? ? ? ? ? ? //獲得文件上傳的流 ? ? ? ? ? ? ? ? InputStream inputStream = fileItem.getInputStream(); ? ? ? ? ? ? ? ? //創(chuàng)建一個文件輸出流 ? ? ? ? ? ? ? ? //realPath=真實的文件夾 ? ? ? ? ? ? ? ? //這只是到最后一級的目錄,還差一個文件;加上輸出文件的名字+"/"uuidFileName; ? ? ? ? ? ? ? ? FileOutputStream fos = new FileOutputStream(realPath + "/" + 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="文件上傳成功!"; ? ? ? ? ? ? ? ? fileItem.delete();//上傳完成,刪除臨時文件 ? ? ? ? ? ? ? ? //===========================文件傳輸完成================== ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return msg; ? ? } }
msg.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> ? ? <title>消息提示</title> </head> <body> ${msg} </body> </html>
WEB-XML
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" ? ? ? ? ?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ? ? ? ? ?xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" ? ? ? ? ?version="4.0"> ? ? <servlet> ? ? ? ? <servlet-name>UpLoadServlet</servlet-name> ? ? ? ? <servlet-class>com.pzy.servlet.UpLoadServlet</servlet-class> ? ? </servlet> ? ? <servlet-mapping> ? ? ? ? <servlet-name>UpLoadServlet</servlet-name> ? ? ? ? <url-pattern>/upload.do</url-pattern> ? ? </servlet-mapping> </web-app>
上傳成功后,可以看到upload文件夾下存在一個有uuid碼組成的文件夾,文件夾下是我們上傳的文件
總結(jié):
1、為保證服務(wù)器安全,上傳文件應(yīng)該放在外界無法直接訪問的目錄下,比如放于WEB-INF目錄下。
2、為防止文件覆蓋的現(xiàn)象發(fā)生,要為上傳文件產(chǎn)生一個唯一的文件名,我們采用為每一個文件創(chuàng)建一個獨一無二的UUID文件夾來保存文件,即使上傳了兩個相同的文件,也要被保存在不同UUID文件名的目錄中
3、要限制上傳文件的最大值,大于最大值會被存放為臨時文件
4、由于JVM運行的是class文件,我們的java文件被編譯為class文件是存放在web目錄中的,因此,最后的上傳地址也是在web目錄下
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot Redis客戶端遠程操作實現(xiàn)過程解析
這篇文章主要介紹了Spring Boot Redis客戶端遠程操作實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04線程池之newCachedThreadPool可緩存線程池的實例
這篇文章主要介紹了線程池之newCachedThreadPool可緩存線程池的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06Java中關(guān)于size()>0?和isEmpt()的性能考量
這篇文章主要介紹了Java中關(guān)于size()>0?和isEmpt()性能考量,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02