Java web file upload

1, Overview
Using jar package

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

Precautions for file upload

In order to ensure the security of the server, the uploaded files should be placed in a directory that cannot be directly accessed by the outside world, such as the WEB-INF directory
In order to prevent file overwriting, a unique file name should be generated for the uploaded file
To limit the maximum number of uploaded files
You can limit the types of uploaded files and judge whether the suffix is legal when you receive the uploaded file name
The method property of the form should be set to the POST method instead of the GET method

2, Classes used
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 using the ServletFileUpload object to parse the request. 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
In the HTML page, the input must have a name. If the form contains a file upload input item, the enctype attribute of the form must be set to multipart / form data. If you want to obtain data on the server side, you must also use the stream

DiskFileItemFactory
Encapsulate the request message of each file item in the disk object as a separate task
By org apache. commons. fileupload. Default implementation of fileitemfactory interface
org.apache.commons.fileupload.disk.DiskFileItemFactory. When the uploaded file items are relatively small, they are directly saved in memory (faster). When they are relatively large, they are saved in the form of temporary files in the temporary folder on the disk (although the speed is slower, the memory resources are limited).

3, Code implementation logic
Judge whether the file uploaded by the user is an ordinary form or a form with files. If it is an ordinary file, return it directly (return)
The path to create file upload and save is safe under the WEB-INF path, and users cannot directly access the uploaded file
Create a temporary path. If the file is better than the expected size, put it into a temporary file
Create a DiskFileItemFactory object and set the temporary path (setRepository) or size limit of the file (set a buffer, setSizeThreshold)
Get the ServletFileUpload object, deal with the problem of garbled code (setHeaderEncoding), set the maximum value of a single file (setFileSizeMax), set the total size of files that can be uploaded (setSizeMax), and choose to listen to the file upload progress (setProgressListener)
Parse the front-end request through the parseRequest method of ServletFileUpload object and encapsulate it into a FileItem object. Judge whether the uploaded file is an ordinary form or a form with a file (isFormField). getFieldName obtains the name of the front-end form control
Get the file name through the getName method of FileItem and judge whether it is empty. UUID can be used to ensure that the file name is unique
Splice the real existence path of files, and create a corresponding folder for each file
Get the file upload stream through the getInputStream method of FileItem, create a file output stream, write the file to the real saving path, and finally close the stream
If the upload is successful, the page can be forwarded to a new prompt page

4, Code implementation
Javaservlet

package org.westos.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.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Judge whether the file uploaded by the user is an ordinary form or a form with files. If it is an ordinary file, return it directly
        if (!ServletFileUpload.isMultipartContent(request)) {
            return;
        }
        //The path to create file upload and save is safe under the WEB-INF path, and users cannot directly access the uploaded file
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        System.out.println(uploadPath);
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()){
            uploadFile.mkdir();
        }
        //Temporary path. If the file is better than the expected size, put it into a temporary file and delete it automatically in a few days, or remind the user to save it permanently
        String tmpPath = this.getServletContext().getRealPath("WEB-INF/tmp");
        File file = new File(tmpPath);
        if (!file.exists()){
            file.mkdir();
        }
        //The uploaded files are generally obtained through streaming. You can use request Getinputstream(), the original file upload stream, is very troublesome
        //It is recommended to use Apache's file upload component to implement common file upload, which depends on the common IO component;
        //1. Create a DiskFileItemFactory object to handle file upload path or size restrictions
        DiskFileItemFactory factory = getDiskFileItemFactory(uploadFile);
        //2. Get ServletFileUpload
        ServletFileUpload upload = getServletFileUpload(factory);
        //3. Process uploaded files
        try {
            String msg = uploadParseRequest(upload,request,uploadPath);
            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();
        //Set a buffer through the factory. When the uploaded file is larger than this buffer, it will be put into the temporary file
        factory.setSizeThreshold(1024*1024); //The buffer size is 1M
        factory.setRepository(file);//A File is required for the directory where temporary files are saved
        return factory;
    }
    public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory){
        ServletFileUpload upload = new ServletFileUpload(factory);
        //Monitor file upload progress
        upload.setProgressListener(new ProgressListener() {
            @Override
            //pBytesRead: the size of the file that has been read
            //pContentLength: file size
            public void update(long pBytesRead, long pContentLength, int pItems) {
                System.out.println("Total size:"+pContentLength+"Uploaded"+pBytesRead);
            }
        });
        //Dealing with garbled code
        upload.setHeaderEncoding("utf-8");
        //Sets the maximum value for a single file
        upload.setFileSizeMax(1024*1024*10);
        //Set the total size of files that can be uploaded
        upload.setSizeMax(1024 * 1024 * 10);
        return upload;
    }
    public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath) throws FileUploadException, IOException {
        String msg = "";
        //Parse the front-end request and encapsulate it into a FileItem object
        List<FileItem> fileItems = upload.parseRequest(request);
        for (FileItem fileItem : fileItems) {
            if (fileItem.isFormField()){
                String name = fileItem.getFieldName();
                String value = fileItem.getString("UTF-8");
                System.out.println(name+":"+value);
            }else {
                //****************************Processing files****************************
                //Get the file name
                String uploadFileName = fileItem.getName();
                System.out.println("Uploaded file name:"+uploadFileName);
                if (uploadFileName.trim().equals("") || uploadFileName==null){
                    continue;
                }
                //Get the uploaded file name
                String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/")+1);
                //Get the suffix of the file
                String fileExName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);
                /*
                * If the file suffix fileExName is not the required direct return, it will not be processed and the user will be told that the file type is wrong
                * */
                System.out.println("file information [File name:"+fileName+"---file type"+fileExName+"]");
                //You can use UUID (unique identification common code) to ensure that the file name is unique
                String uuidPath = UUID.randomUUID().toString();
                //****************************Finished processing files****************************
                //Real path
                String realPath = uploadPath+"/"+uuidPath;
                //Create a folder for each file
                File realPathFile = new File(realPath);
                if (!realPathFile.exists()){
                    realPathFile.mkdir();
                }
                //****************************Storage address completed*****************************
                //Get the stream of file upload
                InputStream inputStream = fileItem.getInputStream();
                //Create a file output stream
                //realPath is a real folder
                FileOutputStream fos = new FileOutputStream(realPath + "/"+fileName);
                //Create a buffer
                byte[] buffer = new byte[1024 * 1024];
                //Judge whether the reading is completed
                int len = 0;
                while ((len=inputStream.read(buffer))>0){
                    fos.write(buffer,0,len);
                }
                //Close flow
                fos.close();
                inputStream.close();
                msg = "File uploaded successfully";
                fileItem.delete();//Upload succeeded, clear temporary files
                //*************************File transfer complete**************************
            }
        }
        return msg;
    }
}

upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>File upload</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload.do" method="post" enctype="multipart/form-data">
    Upload user: <input type="text" name="username"><br/>
    Upload file:<input type="file" name="file"><br/>
    <input type="submit" value="Submit">
</form>
</body>
</html>

msg.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Message prompt</title>
</head>
<body>
    ${msg}
</body>
</html>
web.xml

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>org.westos.servlet.UploadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UploadServlet</servlet-name>
        <url-pattern>/upload.do</url-pattern>
    </servlet-mapping>
</web-app>

Keywords: Java

Added by asuamol on Fri, 04 Mar 2022 15:33:57 +0200