Java web file upload and download

Posted by SpecialFX on Wed, 22 Dec 2021 02:55:59 +0100

Java web file upload and download

Theory (principle analysis):

File download

  1. To get the path of the downloaded file
  2. Downloaded file name (the file name displayed to the client)
  3. Set up a way to make the browser support downloading what we need (attachment;filename)
  4. Create file input stream
  5. Create buffer
  6. Get OutputStream object
  7. Writes the FileOutputStream stream to the buffer buffer
  8. Use OutputStream to output the data in the buffer to the client!
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. To get the path of the downloaded file
    String realPath = "F:\\Class management\\Xikai [19525]\\2,code\\JavaWeb\\javaweb-02-servlet\\response\\target\\classes\\Qin Jiang.png";
    System.out.println("Path to download file:"+realPath);
    // 2. What is the name of the downloaded file?
    String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
    // 3. Set up a way to make the browser support (content disposition) to download what we need. The Chinese file name is urlencoder Encode, otherwise it may be garbled
    resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));
    // 4. Obtain the input stream of the downloaded file
    FileInputStream in = new FileInputStream(realPath);
    // 5. Create buffer
    int len = 0;
    byte[] buffer = new byte[1024];
    // 6. Get OutputStream object
    ServletOutputStream out = resp.getOutputStream();
    // 7. Write the FileOutputStream stream to the buffer, and use OutputStream to output the data in the buffer to the client!
    while ((len=in.read(buffer))>0){
        out.write(buffer,0,len);
    }

    in.close();
    out.close();
}

Note: when setting the header, attach; If the semicolon of filename is accidentally written as a colon, only the picture will be displayed instead of the downloaded picture

File upload

Dependent packages required

  1. commons.io

    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.11.0</version>
    </dependency>
    
  2. commons. FileUpload (dependent on ` ` commons.io ')

    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>
    

Required classes

ServletFileUpload is responsible for processing the uploaded file data and encapsulating each input item of the form into a FileItem object. When using the 'ServletFileUpload' object to parse the request, the 'DiskFileItemFactory' object is required. Therefore, we need to construct the 'DiskFileItemFactory' object before parsing, and set the fileItemFactory property of the ServletFileUpload object through the construction method of the 'ServletFileUpload' object or the 'setFileItemFactory() method

FileItem class

In HTML page, input must have name < input type = "file" name = "filename" >

If the form contains a file upload input item, the enctype attribute of the form must be set to multipart / form data

<form action="" enctype="multipart/form-data" method="post">

    Upload user<input type="text" name="username"><br/>

    <p><input type="file" name="file1"></p>
    <p><input type="file" name="file2"></p>

    <p><input type="submit"> | <input type="reset"></p>

</form>

common method

//The isFormField method is used to judge that the data encapsulated underground by the FileItem class is an ordinary text form
//It is also a file form. If it is an ordinary form field, it returns true; otherwise, it returns false
boolean isFormField();

//The getFiledName() method is used to return the value of the name attribute of the form label.
String getFieldName();
//The getString() method is used to return the data stream content saved in the FileItem object as a string
String getString();

//The getName() method is used to obtain the file name in the file upload field
String getName();

//Return the data content of the uploaded file in the form of stream.
InputStream getInputStream();

//The delete method is used to empty the body content stored in the FileItem class object
//If the body content is saved in a temporary file, the delete method deletes the temporary file.
void delete();

ServletFileUpload class

ServletFileUpload is responsible for processing the uploaded file data and encapsulating each input item in the schema form into a FileItem object. Using its * * parseRequest(HttpServletRequest r) * * method, the data submitted through each HTML tag in the form can be encapsulated into a FileItem object and then returned in the form of List. Using this method to process uploaded files is simple and easy to use.

package com.example.file;

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.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

@WebServlet(name = "FileServlet", value = "/FileServlet")
public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        //Determine whether the uploaded file is a normal form or a form with a file
        if (!ServletFileUpload.isMultipartContent(request)) {
            return;//Terminate the operation of the method, indicating that this is an ordinary form, which is returned directly
        }
        //Create a save path for the uploaded file. It is recommended to save it to the WEB-INF path. The security user cannot directly access the uploaded file
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()) {
            uploadFile.mkdir();//Create this directory
        }
        //Cache, temporary file
        String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
        File tmpFile = new File(tmpPath);
        if (!tmpFile.exists()) {
            tmpFile.mkdir();//Create this temporary directory
        }
        //Process uploaded files
        /*
        ServletFileUpload It is responsible for processing the uploaded file data and encapsulating each input item in the form into a FileItem object
        The DiskFileItemFactory object is required when parsing requests using the ServletFileUpload object
        Therefore, Wimbledon needs to construct the DiskFileItemFactory object before parsing
        Set the fileItemFactory property of the ServletFileUpload object through the construction method of the ServletFileUpload object or the setFileItemFactory() method
         */

        DiskFileItemFactory factory = getDiskFileItemFactory(tmpFile);
        ServletFileUpload servletFileUpload = getServletFileUpload(factory);
        String result = extracted(request, uploadPath, servletFileUpload);
        request.setAttribute("result",result);
        System.out.println(result);
        request.getRequestDispatcher("info.jsp").forward(request,response);



    }

    private String extracted(HttpServletRequest request, String uploadPath, ServletFileUpload servletFileUpload){
        StringBuilder msg = new StringBuilder();
        try{
            //3. Process uploaded files
            //The front-end request is parsed and encapsulated into a FileItem object
            List<FileItem> fileItems = servletFileUpload.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                String name;
                if(fileItem.isFormField()){
                    //getFileName refers to the Name of the front-end form control
                    name = fileItem.getFieldName();
                    String value = fileItem.getString("UTF-8");//Deal with garbled code
                    System.out.println(name+":"+value);
                }else {//file
                    //----------------Processing files-----------------//
                    //Get full file name
                    name = fileItem.getName();
                    //Determine file size
                    if(fileItem.getSize() >= 1024 * 1024 * 10){
                        msg.append(name).append(":").append("Memory limit exceeded, transfer denied<br>");
                        fileItem.delete();//Upload succeeded. Clear the temporary file
                        continue;
                    }
                    //The file name may be illegal
                    if(name == null|| name.trim().equals("")){
                        fileItem.delete();//Upload succeeded. Clear the temporary file
                        continue;
                    }
                    //Get the uploaded file name
                    String fileName = name.substring(name.lastIndexOf('/') + 1);
                    //Get file suffix
                    String fileExtName = name.substring(name.lastIndexOf('.') + 1);
                /*
                     If the suffix is not required, return it directly
                     Tell the user that the file type is incorrect
                 */

                    //You can use UUID (unique identification code) to ensure that the file name is unique
                    //UUID.randomUUID(), which randomly generates an identifying universal code

                    //Everything in network transmission needs to be serialized
                    //Entity class, if you want to run on multiple computers, you need to transfer (serialize all objects)
                    //Implementation serializable: tag interface, JVM -- > java stack, native method stack -- > C++
                    String uuidPath = UUID.randomUUID().toString();


                    //----------------Storage address-----------------//
                    //Storage location uploadPath
                    //The path where the file really exists is realPath
                    String realPath = uploadPath +"/"+uuidPath;
                    //Create a folder for each file
                    File realPathFile = new File(realPath);
                    if(!realPathFile.exists()){
                        realPathFile.mkdir();
                    }


                    //----------------File transfer-----------------//
                    //Get the stream of file upload
                    InputStream is = fileItem.getInputStream();

                    //Create a file output stream
                    FileOutputStream fos = new FileOutputStream(realPath + "/" + name);

                    //Create a buffer
                    byte[] buffer = new byte[1024 * 1024];

                    //Judge whether the reading is completed
                    int len =0;
                    //If it is greater than 0, data still exists
                    while ((len=is.read(buffer))>0){
                        fos.write(buffer,0,len);
                    }

                    //Close flow
                    fos.close();
                    is.close();

                    msg.append(name).append(":Upload succeeded<br>");

                    fileItem.delete();//Upload succeeded. Clear the temporary file
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            return "Upload exception";
        }

        return msg.toString();
    }

    private ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
        //2. Get ServletFileUpload
        ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
        //Monitor file upload progress
//        servletFileUpload. setProgressListener((l, all, i) -> System. out. Println ("total size:" + ALL + "\ tloaded:" + l));
        //Dealing with garbled code
        servletFileUpload.setHeaderEncoding("UTF-8");
        //Sets the maximum value for a single file
//        servletFileUpload.setFileSizeMax(1024 * 1024 * 10);//10M
        //Set the total size of files that can be uploaded
//        servletFileUpload.setSizeMax(1024 * 1024 * 10 * 2);
        /*
            If the size is set, if the size is exceeded, it will be directly abnormal
         */
        return servletFileUpload;
    }

    private DiskFileItemFactory getDiskFileItemFactory(File dir) {
        //1. Create DiskFileItemFactory object to handle file upload path or size limit
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //Set a buffer through the factory. When the uploaded file is larger than the buffer, it will be put into the temporary file
        if(dir!=null){
            factory.setSizeThreshold(1024 * 1024);//The cache size is 1M
            factory.setRepository(dir);
        }
        return factory;
    }
}

Insufficient:

The above code does not really limit the size, but allows the file to be uploaded to the tmp folder before judging whether the size is excessive. At present, I can only judge and limit the size at the front end. The back end will make an exception during conversion. However, this exception will lead to the collapse of the request and the front end will not receive the corresponding reply.

Actual combat (project actual combat):

Project list:

  1. Project directory

  2. Project display







Initialize project

  1. Editor I use: idea2021 two

  2. Project creation


Dependency injection (pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>File</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>File</name>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
      <junit.version>5.7.1</junit.version>
      </properties>

  <dependencies>
                                                                        <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>                                                                        
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
      <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
      <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.11.0</version>
      </dependency>
      <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
      <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.4</version>
      </dependency>
      <!-- JSTL Dependency of expression -->
      <dependency>
          <groupId>javax.servlet.jsp.jstl</groupId>
          <artifactId>jstl-api</artifactId>
          <version>1.2</version>
      </dependency>
      <!-- standard Tag library -->
      <dependency>
          <groupId>taglibs</groupId>
          <artifactId>standard</artifactId>
          <version>1.1.2</version>
      </dependency>


  </dependencies>

  <build>
     <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.1</version>
      </plugin>
     </plugins>
  </build>
</project>

Write (import) static resources

  1. JSP

    1. upload.jsp

      <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
      <!DOCTYPE html>
      <html>
      <head>
        <title>File upload</title>
        <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/css.css"/>
        <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/css2.css"/>
      </head>
      <body>
      
      <div class="form">
      
        <form id="fileForm" action="${pageContext.request.contextPath}/UploadServlet" enctype="multipart/form-data" method="post">
      
          Upload user<input type="text" name="username"><br>
          <br>
          <div>
            <label for="files">Select file upload (multiple selections are allowed)</label>
            <input type="file" id="files" name="files" multiple="" style="opacity: 0;">
          </div>
          <br>
          <div class="preview">
            <p>There are currently no files selected</p>
          </div>
          <br>
          <p>
            <input id="submitBtn" type="button" value="upload"> | <input type="reset" id="resetBtn">
          </p>
        </form>
            <a href="${pageContext.request.contextPath }/DownloadServlet?method=getFileNameList"><button>Go and download the file</button></a>
      </div>
      
      </body>
      
      <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.8.3.min.js"></script>
      <script type="text/javascript" src="${pageContext.request.contextPath }/js/upload.js"></script>
      
      </html>
      
    2. info.jsp

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>Upload file</title>
          <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/css.css"/>
          <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/css2.css"/>
      </head>
      <body>
      
      <div class="form">
          <h2>Upload status:</h2>
          <div>${result}</div>
          <a href="${pageContext.request.contextPath }/upload.jsp"><button>To upload files</button></a>
          <a href="${pageContext.request.contextPath }/DownloadServlet?method=getFileNameList"><button>Go and download the file</button></a>
      </div>
      
      </body>
      
      </html>
      
    3. download.jsp

      <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%>
      <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
      <!DOCTYPE HTML>
      <html>
      <head>
          <title>Download File</title>
          <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/css.css"/>
          <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/css2.css"/>
      </head>
      
      <body>
      
      <div class="form">
          <!-- ergodic Map aggregate -->
          <c:forEach var="me" items="${fileNameMap}">
              <c:url value="/DownloadServlet" var="downurl">
                  <c:param name="path" value="${me.key}"></c:param>
                  <c:param name="realName" value="${me.value}"></c:param>
              </c:url>
              <a href="${downurl}&method=downloadFile">[download]</a>-----<a href="${downurl}&method=previewFile">[preview]</a>${me.value}<br/>
          </c:forEach>
          <a href="${pageContext.request.contextPath }/upload.jsp"><button>To upload files</button></a>
      </div>
      
      </body>
      </html>
      
  2. CSS

    • css.css

      html {
          font-family: sans-serif;
      }
      
      .form {
          width: 580px;
          background: #ccc;
          margin: 0 auto;
          padding: 20px;
          border: 1px solid black;
      }
      
      form ol {
          padding-left: 0;
      }
      
      form li, div > p {
          background: #eee;
          display: flex;
          justify-content: space-between;
          margin-bottom: 10px;
          list-style-type: none;
          border: 1px solid black;
      }
      
      form img {
          height: 64px;
          order: 1;
      }
      
      form p {
          line-height: 32px;
          padding-left: 10px;
      }
      
      form label, form button {
          background-color: #7F9CCB;
          padding: 5px 10px;
          border-radius: 5px;
          border: 1px ridge black;
          font-size: 0.8rem;
          height: auto;
      }
      
      form label:hover, form button:hover {
          background-color: #2D5BA3;
          color: white;
      }
      
      form label:active, form button:active {
          background-color: #0D3F8F;
          color: white;
      }
      
    • css2.css

      body {
          padding: 0;
          margin: 0;
      }
      
      svg:not(:root) {
          display: block;
      }
      
      .playable-code {
          background-color: #f4f7f8;
          border: none;
          border-left: 6px solid #558abb;
          border-width: medium medium medium 6px;
          color: #4d4e53;
          height: 100px;
          width: 90%;
          padding: 10px 10px 0;
      }
      
      .playable-canvas {
          border: 1px solid #4d4e53;
          border-radius: 2px;
      }
      
      .playable-buttons {
          text-align: right;
          width: 90%;
          padding: 5px 10px 5px 26px;
      }
      
      
  3. JavaScript

    • jquery-1.8.3.min.js, I won't write it in. You can download it online

    • upload.js

      const inputFiles = document.getElementById('files');
      const preview = document.querySelector('.preview');
      const submitBtn = $("#submitBtn");
      const resetBtn = $("#resetBtn");
      const fileForm = $("#fileForm");
      const maxSize = 1024*1024*10;//10M single file size limit
      
      inputFiles.style.opacity = 0;
      inputFiles.addEventListener('change', updateImageDisplay);
      
      //Types of pictures that can be displayed
      const fileTypes = [
          'image/jpeg',
          'image/pjpeg',
          'image/png'
      ];
      
      function validFileType(file) {
          return fileTypes.includes(file.type);
      }
      
      function returnFileSize(number) {
          if(number < 1024) {
              return number + 'bytes';
          } else if(number >= 1024 && number < 1048576) {
              return (number/1024).toFixed(1) + 'KB';
          } else if(number >= 1048576) {
              return (number/1048576).toFixed(1) + 'MB';
          }
      }
      
      
      function updateImageDisplay() {
          let isOK = true;
      
          while(preview.firstChild) {
              preview.removeChild(preview.firstChild);
          }
      
          const curFiles = inputFiles.files;
          if(curFiles.length === 0) {
              const para = document.createElement('p');
              para.textContent = 'There are currently no files selected';
              preview.appendChild(para);
              isOK = false;
          } else {
              const list = document.createElement('ol');
              preview.appendChild(list);
      
              for(const file of curFiles) {
                  const listItem = document.createElement('li');
                  const para = document.createElement('p');
                  para.textContent = "File name: "+file.name+", File size: "+returnFileSize(file.size);
      
                  //Judge whether the limit is exceeded according to the file size
                  if(file.size >= maxSize){
                      para.style.color = "red";
                      isOK = false;
                  }else {
                      para.style.color = "green";
                  }
      
                  //If it is a picture type, the picture is displayed
                  if(validFileType(file)) {
                      const image = document.createElement('img');
                      image.src = URL.createObjectURL(file);
                      listItem.appendChild(image);
                  }
      
                  listItem.appendChild(para);
      
                  list.appendChild(listItem);
              }
      
          }
          return isOK;
      }
      
      submitBtn.bind("click",function () {
          if(updateImageDisplay()){
              if(confirm("Are you sure you want to upload these files?")){
                  fileForm.submit();
              }else {
                  alert("No file is selected or the selected file does not meet the upload requirements!");
              }
          }
      })
      
      resetBtn.bind("click",function () {
          setTimeout(updateImageDisplay,200);
      })
      

Writing servlets

web.xml

There is no Servlet mapping written here. The mapping is directly done by the @ webservlet (name = ---, value = / -) annotation in the Servlet. So only on the web A welcome page is set in 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">

    <!--Set up welcome page-->
    <welcome-file-list>
        <welcome-file>upload.jsp</welcome-file>
    </welcome-file-list>

</web-app>

UploadServlet

package com.example.file;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

@WebServlet(name = "UploadServlet", value = "/UploadServlet")
public class UploadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        //Determine whether the uploaded file is a normal form or a form with a file
        if (!ServletFileUpload.isMultipartContent(request)) {
            return;//Terminate the operation of the method, indicating that this is an ordinary form, which is returned directly
        }
        //Create a save path for the uploaded file. It is recommended to save it to the WEB-INF path. The security user cannot directly access the uploaded file
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()) {
            uploadFile.mkdir();//Create this directory
        }
        //Cache, temporary file
        String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
        File tmpFile = new File(tmpPath);
        if (!tmpFile.exists()) {
            tmpFile.mkdir();//Create this temporary directory
        }
        //Process uploaded files
        /*
        ServletFileUpload It is responsible for processing the uploaded file data and encapsulating each input item in the form into a FileItem object
        The DiskFileItemFactory object is required when parsing requests using the ServletFileUpload object
        Therefore, Wimbledon needs to construct the DiskFileItemFactory object before parsing
        Set the fileItemFactory property of the ServletFileUpload object through the construction method of the ServletFileUpload object or the setFileItemFactory() method
         */

        DiskFileItemFactory factory = getDiskFileItemFactory(tmpFile);
        ServletFileUpload servletFileUpload = getServletFileUpload(factory);
        String result = extracted(request, uploadPath, servletFileUpload);
        request.setAttribute("result",result);
        System.out.println(result);
        request.getRequestDispatcher("info.jsp").forward(request,response);



    }

    private String extracted(HttpServletRequest request, String uploadPath, ServletFileUpload servletFileUpload){
        StringBuilder msg = new StringBuilder();
        try{
            //3. Process uploaded files
            //The front-end request is parsed and encapsulated into a FileItem object
            List<FileItem> fileItems = servletFileUpload.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                String name;
                if(fileItem.isFormField()){
                    //getFileName refers to the Name of the front-end form control
                    name = fileItem.getFieldName();
                    String value = fileItem.getString("UTF-8");//Deal with garbled code
                    System.out.println(name+":"+value);
                }else {//file
                    //----------------Processing files-----------------//
                    //Get full file name
                    name = fileItem.getName();
                    //Determine file size
                    if(fileItem.getSize() >= 1024 * 1024 * 10){
                        msg.append(name).append(":").append("Memory limit exceeded, transfer denied<br>");
                        fileItem.delete();//Upload succeeded. Clear the temporary file
                        continue;
                    }
                    //The file name may be illegal
                    if(name == null|| name.trim().equals("")){
                        fileItem.delete();//Upload succeeded. Clear the temporary file
                        continue;
                    }
                    //Get the uploaded file name
                    String fileName = name.substring(name.lastIndexOf('/') + 1);
                    //Get file suffix
                    String fileExtName = name.substring(name.lastIndexOf('.') + 1);
                /*
                     If the suffix is not required, return it directly
                     Tell the user that the file type is incorrect
                 */

                    //You can use UUID (unique identification code) to ensure that the file name is unique
                    //UUID.randomUUID(), which randomly generates an identifying universal code

                    //Everything in network transmission needs to be serialized
                    //Entity class, if you want to run on multiple computers, you need to transfer (serialize all objects)
                    //Implementation serializable: tag interface, JVM -- > java stack, native method stack -- > C++
                    String uuidPath = UUID.randomUUID().toString();


                    //----------------Storage address-----------------//
                    //Storage location uploadPath
                    //Real path of the file realPath = uploadPath/uuid_fileName
                    String realPath = uploadPath + "/" +uuidPath + "_" + name;
                    System.out.println(realPath);


                    //----------------File transfer-----------------//
                    //Get the stream of file upload
                    InputStream is = fileItem.getInputStream();

                    //Create a file output stream
                    FileOutputStream fos = new FileOutputStream(realPath);

                    //Create a buffer
                    byte[] buffer = new byte[1024 * 1024];

                    //Judge whether the reading is completed
                    int len =0;
                    //If it is greater than 0, data still exists
                    while ((len=is.read(buffer))>0){
                        fos.write(buffer,0,len);
                    }

                    //Close flow
                    fos.close();
                    is.close();

                    msg.append(name).append(":Upload succeeded<br>");

                    fileItem.delete();//Upload succeeded. Clear the temporary file
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            return "Upload exception";
        }

        return msg.toString();
    }

    private ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
        //2. Get ServletFileUpload
        ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
        //Monitor file upload progress
//        servletFileUpload. setProgressListener((l, all, i) -> System. out. Println ("total size:" + ALL + "\ tloaded:" + l));
        //Dealing with garbled code
        servletFileUpload.setHeaderEncoding("UTF-8");
        //Sets the maximum value for a single file
//        servletFileUpload.setFileSizeMax(1024 * 1024 * 10);//10M
        //Set the total size of files that can be uploaded
//        servletFileUpload.setSizeMax(1024 * 1024 * 10 * 2);
        /*
            If the size is set, if the size is exceeded, it will be directly abnormal
         */
        return servletFileUpload;
    }

    private DiskFileItemFactory getDiskFileItemFactory(File dir) {
        //1. Create DiskFileItemFactory object to handle file upload path or size limit
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //Set a buffer through the factory. When the uploaded file is larger than the buffer, it will be put into the temporary file
        if(dir!=null){
            factory.setSizeThreshold(1024 * 1024);//The cache size is 1M
            factory.setRepository(dir);
        }
        return factory;
    }
}

DownloadServlet

package com.example.file;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

@WebServlet(name = "UploadServlet", value = "/UploadServlet")
public class UploadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        //Determine whether the uploaded file is a normal form or a form with a file
        if (!ServletFileUpload.isMultipartContent(request)) {
            return;//Terminate the operation of the method, indicating that this is an ordinary form, which is returned directly
        }
        //Create a save path for the uploaded file. It is recommended to save it to the WEB-INF path. The security user cannot directly access the uploaded file
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()) {
            uploadFile.mkdir();//Create this directory
        }
        //Cache, temporary file
        String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
        File tmpFile = new File(tmpPath);
        if (!tmpFile.exists()) {
            tmpFile.mkdir();//Create this temporary directory
        }
        //Process uploaded files
        /*
        ServletFileUpload It is responsible for processing the uploaded file data and encapsulating each input item in the form into a FileItem object
        The DiskFileItemFactory object is required when parsing requests using the ServletFileUpload object
        Therefore, Wimbledon needs to construct the DiskFileItemFactory object before parsing
        Set the fileItemFactory property of the ServletFileUpload object through the construction method of the ServletFileUpload object or the setFileItemFactory() method
         */

        DiskFileItemFactory factory = getDiskFileItemFactory(tmpFile);
        ServletFileUpload servletFileUpload = getServletFileUpload(factory);
        String result = extracted(request, uploadPath, servletFileUpload);
        request.setAttribute("result",result);
        System.out.println(result);
        request.getRequestDispatcher("info.jsp").forward(request,response);



    }

    private String extracted(HttpServletRequest request, String uploadPath, ServletFileUpload servletFileUpload){
        StringBuilder msg = new StringBuilder();
        try{
            //3. Process uploaded files
            //The front-end request is parsed and encapsulated into a FileItem object
            List<FileItem> fileItems = servletFileUpload.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                String name;
                if(fileItem.isFormField()){
                    //getFileName refers to the Name of the front-end form control
                    name = fileItem.getFieldName();
                    String value = fileItem.getString("UTF-8");//Deal with garbled code
                    System.out.println(name+":"+value);
                }else {//file
                    //----------------Processing files-----------------//
                    //Get full file name
                    name = fileItem.getName();
                    //Determine file size
                    if(fileItem.getSize() >= 1024 * 1024 * 10){
                        msg.append(name).append(":").append("Memory limit exceeded, transfer denied<br>");
                        fileItem.delete();//Upload succeeded. Clear the temporary file
                        continue;
                    }
                    //The file name may be illegal
                    if(name == null|| name.trim().equals("")){
                        fileItem.delete();//Upload succeeded. Clear the temporary file
                        continue;
                    }
                    //Get the uploaded file name
                    String fileName = name.substring(name.lastIndexOf('/') + 1);
                    //Get file suffix
                    String fileExtName = name.substring(name.lastIndexOf('.') + 1);
                /*
                     If the suffix is not required, return it directly
                     Tell the user that the file type is incorrect
                 */

                    //You can use UUID (unique identification code) to ensure that the file name is unique
                    //UUID.randomUUID(), which randomly generates an identifying universal code

                    //Everything in network transmission needs to be serialized
                    //Entity class, if you want to run on multiple computers, you need to transfer (serialize all objects)
                    //Implementation serializable: tag interface, JVM -- > java stack, native method stack -- > C++
                    String uuidPath = UUID.randomUUID().toString();


                    //----------------Storage address-----------------//
                    //Storage location uploadPath
                    //Real path of the file realPath = uploadPath/uuid_fileName
                    String realPath = uploadPath + "/" +uuidPath + "_" + name;
                    System.out.println(realPath);


                    //----------------File transfer-----------------//
                    //Get the stream of file upload
                    InputStream is = fileItem.getInputStream();

                    //Create a file output stream
                    FileOutputStream fos = new FileOutputStream(realPath);

                    //Create a buffer
                    byte[] buffer = new byte[1024 * 1024];

                    //Judge whether the reading is completed
                    int len =0;
                    //If it is greater than 0, data still exists
                    while ((len=is.read(buffer))>0){
                        fos.write(buffer,0,len);
                    }

                    //Close flow
                    fos.close();
                    is.close();

                    msg.append(name).append(":Upload succeeded<br>");

                    fileItem.delete();//Upload succeeded. Clear the temporary file
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            return "Upload exception";
        }

        return msg.toString();
    }

    private ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
        //2. Get ServletFileUpload
        ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
        //Monitor file upload progress
//        servletFileUpload. setProgressListener((l, all, i) -> System. out. Println ("total size:" + ALL + "\ tloaded:" + l));
        //Dealing with garbled code
        servletFileUpload.setHeaderEncoding("UTF-8");
        //Sets the maximum value for a single file
//        servletFileUpload.setFileSizeMax(1024 * 1024 * 10);//10M
        //Set the total size of files that can be uploaded
//        servletFileUpload.setSizeMax(1024 * 1024 * 10 * 2);
        /*
            If the size is set, if the size is exceeded, it will be directly abnormal
         */
        return servletFileUpload;
    }

    private DiskFileItemFactory getDiskFileItemFactory(File dir) {
        //1. Create DiskFileItemFactory object to handle file upload path or size limit
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //Set a buffer through the factory. When the uploaded file is larger than the buffer, it will be put into the temporary file
        if(dir!=null){
            factory.setSizeThreshold(1024 * 1024);//The cache size is 1M
            factory.setRepository(dir);
        }
        return factory;
    }
}

Confusion and doubt

  1. When I set the size limit for ServletFileUpload, if the file passed in from the front end exceeds the limit, an exception will appear, which is not an ordinary exception. It will lead to the direct failure of the request. The desired effect cannot be obtained during subsequent forwarding and redirection. Reference to the online blog (Capturing exceptions, forwarding and redirecting in the catch block) still can not solve the problem.

Reference and thanks

oad servletFileUpload = new ServletFileUpload(factory);
//Monitor file upload progress
// servletFileUpload. setProgressListener((l, all, i) -> System. out. Println ("total size:" + ALL + "\ tloaded:" + l));
//Dealing with garbled code
servletFileUpload.setHeaderEncoding("UTF-8");
//Sets the maximum value for a single file
// servletFileUpload.setFileSizeMax(1024 * 1024 * 10);//10M
//Set the total size of files that can be uploaded
// servletFileUpload.setSizeMax(1024 * 1024 * 10 * 2);
/*
If the size is set, if the size is exceeded, it will be directly abnormal
*/
return servletFileUpload;
}

private DiskFileItemFactory getDiskFileItemFactory(File dir) {
    //1. Create DiskFileItemFactory object to handle file upload path or size limit
    DiskFileItemFactory factory = new DiskFileItemFactory();
    //Set a buffer through the factory. When the uploaded file is larger than the buffer, it will be put into the temporary file
    if(dir!=null){
        factory.setSizeThreshold(1024 * 1024);//The cache size is 1M
        factory.setRepository(dir);
    }
    return factory;
}

}

### Confusion and doubt

1. When I give ServletFileUpload When the size limit is set, if the file passed in from the front end exceeds the limit, an exception will occur. It is not an ordinary exception. It will cause request direct**Break**,Subsequent forwarding and redirection can not get the desired effect. Refer to the online blog (catch exceptions in catch Block forwarding and redirection) still can not solve the problem.

### Reference and thanks

1. thank B Station madness said to provide javaweb Learning video, this article is written with reference to this video

Topics: Java