java file upload

java file upload

1, Preparatory work

For file upload, the browser submits the file to the server in the form of stream in the process of uploading.
Apache's open source tool common fileUpload is generally used as the file upload component.
Common file upload depends on the common IO package, so you need to download this package.

Let's download the latest jar package:

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

Use it as the jar package of the project:

We can also use maven to build, as shown in the following figure:

2, Upload files

2.1. Compile upload and receive message page

The code is as follows:

  • Upload the page jsp

    <%@ page language="java" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML>
    <html>
    <head>
        <title>File upload</title>
    </head>
    
    <body>
    <form action="${pageContext.request.contextPath}/UploadHandleServlet" enctype="multipart/form-data" method="post">
        Upload user:<input type="text" name="username"><br/>
        Upload file 1:<input type="file" name="file1"><br/>
        Upload file 2:<input type="file" name="file2"><br/>
        <input type="submit" value="Submit">
    </form>
    </body>
    </html>
    
  • MSG of the received message page jsp

    <%@ page language="java" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML>
    <html>
    <head>
        <title>Message prompt</title>
    </head>
    
    <body>
    ${msg}
    </body>
    </html>
    

2.2. Precautions for file upload

  1. In order to ensure the security of the server, the uploaded files should be placed in a directory that cannot be accessed by the outside world, such as WEN-INF.

  2. To prevent overwriting of files with the same name, specify a unique file name for the file.

  3. Limit the size of uploaded files.

  4. Limit the type of uploaded files. When receiving a file, judge whether the file name is legal.

  5. In order to prevent too many files under a directory, hash algorithm can be used to break up the storage.

2.3. Detailed description of classes and methods to be used

2.3.1 introduction to common classes

  1. ServletFileUpload is responsible for processing the uploaded file data and encapsulating each input item in the form into a FileItem object. DiskFileItemFactory object is required when using 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 ServletFileItem object or setFileItemFactory().

  2. FileItem class

    You must have a name in the HTML page:

  3. Upload file:

    If the form contains a file upload item, the entype attribute of the form must be set to multipart / form data. If the form type of the browser is multipart / form data, the server needs to get the data through the stream.

2.3.2 introduction to common methods

  • The isFormFile method is used to judge whether the data encapsulated by the FileItem class object is a normal text form / / or a file form. If it is a normal form field, it returns true; otherwise, it returns false

  • booleanisField();// The getfieldname 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 will delete the temporary file

  • ServletFileUpload is responsible for processing the uploaded file data, and encapsulating each input item in the form into a FileItem object. Using its parseRequest(HttpServletRequest) 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.

2.4 source code

2.4.1. We can encapsulate common methods in tool classes

package Utils;

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 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 uploadUtil {
    public static DiskFileItemFactory getFactory(File file) {

        DiskFileItemFactory factory = new DiskFileItemFactory();

        //Set a buffer. If the file size exceeds the buffer, put it in the temporary path
        factory.setSizeThreshold(1024 * 1024 * 5);
        factory.setRepository(file);
        return factory;
    }

    public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
        ServletFileUpload upload = new ServletFileUpload(factory);
        //Monitor file upload progress
        upload.setProgressListener (new ProgressListener() {
            @Override
            public void update(long pBytesRead, long pContentlenth, int pItems) {
                //Pcontentlence: file size
                //pBytesRead: read file size
                System.out.println("Total size:" + pContentlenth + "   Uploaded:" + pBytesRead);
            }
        });
        //Prevent garbled code
        upload.setHeaderEncoding("UTF-8");

        //Set the maximum value of uploading a single file (1 M)
        upload.setFileSizeMax(1024 * 1024);

        //Set the total size of files that can be uploaded
        upload.setSizeMax(1024 * 1024 * 10);

        return upload;
    }

    public static String upLoadParseRequest(ServletFileUpload upload, javax.servlet.http.HttpServletRequest request, String uploadPath) throws IOException, FileUploadException {
        String msg = "";
        //The servlet fileUpload parser is used to parse the uploaded data. The parsing result returns a list < FileItem > collection, and each FileItem corresponds to an input item of the Form
        List<FileItem> fileItems = upload.parseRequest(request);
        for (FileItem fileItem : fileItems) {
            //Determine whether it is an ordinary form
            if (fileItem.isFormField()) {
                //Normal form
                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);
                //Determine whether the file name exists
                if (uploadFileName.trim().equals("") || uploadFileName == null) {
                    continue;
                }
                //Get the real file name (remove the redundant path)
                String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                //Get file suffix
                String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);

                //If the file suffix does not match, return it directly and do not process it
                System.out.println("file information[ File name:" + fileName + "----File type:" + fileExtName + "]");



                //=====================================File processing completed========================================

                //=====================================Storage address processing========================================
                //Get the name of the file to save
                String saveFilename = makeFileName(fileName);
                //Get the save directory of the file
                String realPath = makePath(saveFilename, uploadPath);
                //====================================Storage address processed=====================================

                //Get file upload stream
                InputStream inputStream = fileItem.getInputStream();

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

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

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

                fos.close();
                inputStream.close();

                msg = "File uploaded successfully";
                //Clear temporary files
                //fileItem.delete();
            }

        }
        return msg;
    }
    /**
     * @Method: makeFileName
     * @Description: Generate the file name of the uploaded file. The file name is: uuid + ""+ The original name of the file
     * @param filename The original name of the file
     * @return uuid+"_"+The original name of the file
     */
    public static String makeFileName(String filename){  //2.jpg
        //In order to prevent file overwriting, a unique file name should be generated for the uploaded file
        return UUID.randomUUID().toString() + "_" + filename;
    }

    /**
     * In order to prevent too many files under a directory, hash algorithm should be used to break up the storage
     * @Method: makePath
     * @param filename File name. The storage directory should be generated according to the file name
     * @param savePath File storage path
     * @return New storage directory
     */
    public static String makePath(String filename,String savePath){
        //The filename of the object in memory is the value of the hash code
        int hashcode = filename.hashCode();
        int dir1 = hashcode&0xf;  //0--15
        int dir2 = (hashcode&0xf0)>>4;  //0-15
        //Construct a new save directory
        String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
        //File can represent either a file or a directory
        File file = new File(dir);
        //If the directory does not exist
        if(!file.exists()){
            //Create directory
            file.mkdirs();
        }
        return dir;
    }
}

2.4.2. Write servlet

package servlet;

import org.apache.commons.fileupload.FileUploadException;
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.IOException;
import static Utils.uploadUtil.*;

@javax.servlet.annotation.WebServlet("/UploadHandleServlet")
public class UploadHandleServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //Judge whether the uploaded form has files
            if (!ServletFileUpload.isMultipartContent(request)) {
                //If it is a normal text form, return directly
                return ;
            }
            //Form with file

            //Create the save path of the uploaded file. It is recommended to be safe under WEB-INF
            String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
            File file1 = new File(uploadPath);
            if (!file1.exists()) {
                file1.mkdir();
            }

            //Temporary path. The file exceeds the expected size. Put it here
            String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
            System.out.println(tempPath);
            File file = new File(tempPath);
            if (!file.exists()) {
                file.mkdir();
            }


            //1. Create DiskFileItemFactory object, handle file size, path, etc
            DiskFileItemFactory factory = getFactory(file);

            //2. Get ServletFileUpload
            ServletFileUpload upload = getServletFileUpload(factory);

            //3. Process uploaded files
            String msg = upLoadParseRequest(upload, request, uploadPath);

            request.setAttribute("msg", msg);
            request.getRequestDispatcher("msg.jsp").forward(request, response);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

2.5 effect display


Check the WEB-INF file again

Keywords: Java

Added by Stuie_b on Tue, 08 Feb 2022 01:25:22 +0200