文件上传

文件上传

1、准备工作

  1. 创建项目,用maven创建尽量不要手动导包,避免出现web.xml实例化错误。

  2. 导入common-io和common-fileupload包:

    地址:https://mvnrepository.com/artifact/commons-io/commons-io/2.6

    https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload/1.4

  3. maven导包

    <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>servlet-api</artifactId>
         <version>2.5</version>
       </dependency>
       <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
       <dependency>
         <groupId>commons-io</groupId>
         <artifactId>commons-io</artifactId>
         <version>2.6</version>
       </dependency>
    ​
       <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
       <dependency>
         <groupId>commons-fileupload</groupId>
         <artifactId>commons-fileupload</artifactId>
         <version>1.4</version>
    </dependency>

2、注意事项

  1. 为保证服务器安全,文件上传可存放在WEB-INF目录下

  2. 为防止文件覆盖,要使文件名不同,可用uuid

  3. 要限制文件大小

  4. 可以根据文件后缀限制文件格式

3、代码实现

  1. 判断前端请求的表单是否含有文件 enctype="multipart/form-data"

    if (!ServletFileUpload.isMultipartContent(req)) {
               return;
          }

     

  2. 因为get方法传的参数大小有限制,所以要用post方法 method="post"

    <form action="${pageContext.request.contextPath}/f1" enctype="multipart/form-data" method="post">
       <p><input type="text" name="name"><br>
       <input type="file" name="file1"><br>
       <input type="file" name="file2"><br>
       <input type="submit"> | <input type="reset"></p>
    </form>

     

  3. 设置存放路径和临时存放路径

    // 创建文件存放路径
           String uploadPath = this.getServletContext().getRealPath("WEB-INF/uploadPath");
           File uploadFile = new File(uploadPath);
           if (!uploadFile.exists()) {
               uploadFile.mkdir();
          }
           // 创建临时存放路径
           String tmpPath = this.getServletContext().getRealPath("WEB-INF/tmpPath");
           File file = new File(tmpPath);
           if (!uploadFile.exists()) {
               file.mkdir();
          }
  4. 创建 DiskFileItemFactory

    public DiskFileItemFactory getDiskFileItemFactory(File file) {
           DiskFileItemFactory factory = new DiskFileItemFactory();
           factory.setRepository(file); // 设置临时文件存放位置
           factory.setSizeThreshold(1024 * 1024); /// 设置缓冲区大小
           factory.setDefaultCharset("utf-8"); // 设置字符集
           
           return factory;
      }
  5. 创建FileUpload

    public FileUpload getFileUpload(DiskFileItemFactory factory) {
           FileUpload upload = new FileUpload();
      upload.setFileItemFactory(factory); // 也可以通过构造器传FileUpload upload = new FileUpload(factory);
           upload.setFileSizeMax(1024 * 1024); // 设置文件最大为(单个文件最大) 1M
           upload.setSizeMax(1024 * 1024 * 15); // 设置最大存放总量(所有文件加起来) 15m
           upload.setHeaderEncoding("utf-8"); // 指定编码
           
           upload.setProgressListener(new ProgressListener() { // 监听
               @Override
               public void update(long l, long l1, int i) { // l:文件大小 l1文件已上传的大小
                   System.out.println("已上传" + l1 + "/" + l);
              }
          });
           return upload;
      }
  6. 封装文件对象,判断是否是文件,将文件转换为流, 拼接文件路径,写入服务器

    public String msg(FileUpload upload, String uploadPath, HttpServletRequest req) {
           List<FileItem> fileItems = null;
           InputStream in = null;
           FileOutputStream fos = null;
           String msg = "文件上传失败";
           try {
               fileItems = upload.parseRequest(req);
               for (FileItem fileItem : fileItems) {
                   if (fileItem.isFormField()) { // 判断是否是文件, 不是则不用上传 true不是文件
                       String name = fileItem.getFieldName();  // 获取表单的name
                       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; // 如果文件名为空
                      }
    ​
                       String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("\\") + 1); // 获取文件名
                       String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); // 获取文佳格式
                       System.out.println("文件信息 [件名:" + fileName + "---文件类型" + fileExtName + "]");
    ​
                       // uuid创建文目录防止文件覆盖
                       String uuidPath = UUID.randomUUID().toString();
    ​
                       // 拼接文件存放路径
                       String realPath = uploadPath + "\\" + uuidPath;
                       File realPathFile = new File(realPath);
                       // 如果没有该目录创建目录
                       if (!realPathFile.exists()) {
                           realPathFile.mkdir();
                      }
    ​
                       // 将文件转变换为流
                       in = fileItem.getInputStream();
                       fos = new FileOutputStream(realPath + "\\" + fileName);
                       byte[] buffer = new byte[1024 * 1024];
                       int len = 0;
                       while ((len = in.read(buffer)) != -1) {
                           fos.write(buffer, 0, len);
                      }
    ​
                       msg = "文件上传成功";
                       fileItem.delete(); //上传成功,清除临时文件
                  }
              }
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               try {
                   in.close();
                   fos.close();
    ​
              } catch (IOException e) {
                   e.printStackTrace();
              }
    ​
          }
           return msg;
      }

 

4、完整代码

1. Fileup.java

package com.kuang.servlet;
​
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
​
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
​
public class FileUp1 extends HttpServlet {
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       if (!ServletFileUpload.isMultipartContent(req)) { // 判断表单是否有 enctype="multipart/form-data"
           return;
      }
       // 创建文件存放路径
       String uploadPath = this.getServletContext().getRealPath("WEB-INF/uploadPath");
       File uploadFile = new File(uploadPath);
       if (!uploadFile.exists()) {
           uploadFile.mkdir();
      }
       // 创建临时存放路径
       String tmpPath = this.getServletContext().getRealPath("WEB-INF/tmpPath");
       File file = new File(tmpPath);
       if (!uploadFile.exists()) {
           file.mkdir();
      }
​
       DiskFileItemFactory factory = getDiskFileItemFactory(file);
       FileUpload upload = getFileUpload(factory);
       String msg = msg(upload, uploadPath, req);
       req.setAttribute("msg", msg);
       req.getRequestDispatcher("/msg.jsp").forward(req, resp);
​
​
  }
​
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req, resp);
  }
​
   public DiskFileItemFactory getDiskFileItemFactory(File file) {
       DiskFileItemFactory factory = new DiskFileItemFactory();
       factory.setRepository(file); // 设置临时文件存放位置
       factory.setSizeThreshold(1024 * 1024); /// 设置缓冲区大小
       factory.setDefaultCharset("utf-8"); // 设置字符集
​
       return factory;
  }
​
   publicFileUploadgetFileUpload(DiskFileItemFactoryfactory) {
       FileUploadupload=newFileUpload();
       upload.setFileSizeMax(1024*1024); // 设置文件最大为(单个文件最大) 1M
       upload.setSizeMax(1024*1024*15); // 设置最大存放总量(所有文件加起来) 15m
       upload.setHeaderEncoding("utf-8"); // 指定编码
       upload.setFileItemFactory(factory); // 也可以通过构造器传FileUpload upload = new FileUpload(factory);
       upload.setProgressListener(newProgressListener() { // 监听
           @Override
           publicvoidupdate(longl, longl1, inti) { // l1:文件大小 l文件已上传的大小
               System.out.println("已上传"+l+"/"+l1);
          }
      });
       returnupload;
  }
​
   publicStringmsg(FileUploadupload, StringuploadPath, HttpServletRequestreq) {
       List<FileItem>fileItems=null;
       InputStreamin=null;
       FileOutputStreamfos=null;
       Stringmsg="文件上传失败";
       try {
           fileItems=upload.parseRequest(req);
           for (FileItemfileItem : fileItems) {
               if (fileItem.isFormField()) { // 判断是否是文件, 不是则不用上传 true不是文件
                   Stringname=fileItem.getFieldName();  // 获取表单的name
                   Stringvalue=fileItem.getString("utf-8");  // 获取到用户输入的值
                   System.out.println(name+":"+value);
              } else {
                   StringuploadFileName=fileItem.getName(); // 获取文件名路径
                   System.out.println("文件路径"+uploadFileName);
​
                   if (uploadFileName.trim().equals("") ||uploadFileName==null) {
                       continue; // 如果文件名为空
                  }
​
                   StringfileName=uploadFileName.substring(uploadFileName.lastIndexOf("\\") +1); // 获取文件名
                   StringfileExtName=uploadFileName.substring(uploadFileName.lastIndexOf(".") +1); // 获取文佳格式
                   System.out.println("文件信息 [件名:"+fileName+"---文件类型"+fileExtName+"]");
​
                   // uuid创建文目录防止文件覆盖
                   StringuuidPath=UUID.randomUUID().toString();
​
                   // 拼接文件存放路径
                   StringrealPath=uploadPath+"\\"+uuidPath;
                   FilerealPathFile=newFile(realPath);
                   // 如果没有该目录创建目录
                   if (!realPathFile.exists()) {
                       realPathFile.mkdir();
                  }
​
                   // 将文件转变换为流
                   in=fileItem.getInputStream();
                   fos=newFileOutputStream(realPath+"\\"+fileName);
                   byte[] buffer=newbyte[1024*1024];
                   intlen=0;
                   while ((len=in.read(buffer)) !=-1) {
                       fos.write(buffer, 0, len);
                  }
​
                   msg="文件上传成功";
                   fileItem.delete(); //上传成功,清除临时文件
              }
          }
      } catch (Exceptione) {
           e.printStackTrace();
      } finally {
           try {
               in.close();
               fos.close();
​
          } catch (IOExceptione) {
               e.printStackTrace();
          }
​
      }
       returnmsg;
  }
}
​

2.index.jsp

<%--
 Created by IntelliJ IDEA.
 User: WH
 Date: 2022/4/28
 Time: 15:28
 To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/f1" enctype="multipart/form-data" method="post">
   <p><input type="text" name="name"><br>
   <input type="file" name="file1"><br>
   <input type="file" name="file2"><br>
   <input type="submit"> | <input type="reset"></p>
</form>
​
</body>
</html>
​

3、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"
        metadata-complete="true">
   
   <servlet>
       <servlet-name>FileUp1</servlet-name>
       <servlet-class>com.kuang.servlet.FileUp1</servlet-class>
   </servlet>
   <servlet-mapping>
       <servlet-name>FileUp1</servlet-name>
       <url-pattern>/f1</url-pattern>
   </servlet-mapping>
</web-app>

4、msg.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>消息提示</title>
</head>
<body>
${msg}
</body>
</html>
 

 

 

posted @ 2022-04-28 16:58  致简  阅读(352)  评论(0)    收藏  举报