JavaWeb實現(xiàn)上傳文件功能
本文實例為大家分享了JavaWeb實現(xiàn)上傳文件的具體代碼,供大家參考,具體內(nèi)容如下
這是需要使用到的兩個jar包一定要導入到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)建一個臨時路徑, 假如文件超過了預期的大小,我們就把他放在一個臨時文件下,過幾天自動刪除,或者提醒用戶轉(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ū),當上傳的文件大于這個緩沖區(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)建一個對應的文件夾
? ? ? ? ? ? ? ? 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ù)器安全,上傳文件應該放在外界無法直接訪問的目錄下,比如放于WEB-INF目錄下。
2、為防止文件覆蓋的現(xiàn)象發(fā)生,要為上傳文件產(chǎn)生一個唯一的文件名,我們采用為每一個文件創(chuàng)建一個獨一無二的UUID文件夾來保存文件,即使上傳了兩個相同的文件,也要被保存在不同UUID文件名的目錄中
3、要限制上傳文件的最大值,大于最大值會被存放為臨時文件
4、由于JVM運行的是class文件,我們的java文件被編譯為class文件是存放在web目錄中的,因此,最后的上傳地址也是在web目錄下
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot Redis客戶端遠程操作實現(xiàn)過程解析
這篇文章主要介紹了Spring Boot Redis客戶端遠程操作實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04
線程池之newCachedThreadPool可緩存線程池的實例
這篇文章主要介紹了線程池之newCachedThreadPool可緩存線程池的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
Java中關(guān)于size()>0?和isEmpt()的性能考量
這篇文章主要介紹了Java中關(guān)于size()>0?和isEmpt()性能考量,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02

