Java Web Learning - how to upload files

Keywords: JSP Apache Java xml

Java Web Learning (12) - how to upload files

01 source code display

Servlet source code:

Preparation: need to import common IO and common file upload components

package com.hooi.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.HttpServlet;
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 HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        /*
            1. Determine whether the user's request is a normal form or a form with files through ServletFileUpload
         */
        if (!ServletFileUpload.isMultipartContent(req)){
            //If it is a normal form, return directly
            return;
            //If it's a form with a file, go to step 2
        }


        /*
            2. It is recommended to save the file in the WEB-INF path. It is safe and the user cannot directly access the file in this path.
         */

        //2.1 real saving path for creating files
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()){
            //If the directory does not exist, create it
            uploadFile.mkdir();
        }
        //2.2 create a temporary path. If the file exceeds the expected size, store it in the temporary path first, and delete the temporary file after uploading.
        String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
        File tmpfile = new File(tmpPath);
        if (!tmpfile.exists()){
            //If the directory does not exist, create it
            tmpfile.mkdir();
        }

        //===========================This completes the path creation===========================

        /*
            3.Use DiskFileItemFactory to process the directory where temporary files are saved:
              For example: processing file upload path and limiting file size
              
              In general, it can be obtained through flow.
              For example, request.getInputStream(),
              However, it is very troublesome to use the original ecological flow to obtain documents.
              Therefore, we use the common file upload component of Apache to implement.
              This component depends on the common IO component.
              
         */

        //3.1. Create DiskFileItemFactory object
        DiskFileItemFactory factory = new DiskFileItemFactory();

        //3.2 set the buffer through the factory. When the upload file is larger than the buffer size, save the file to the temporary file first.
        factory.setSizeThreshold(1024*1024);//Cache size is 1M
        factory.setRepository(tmpfile);//Set the directory where temporary files are saved, which needs to be transferred in

        //========================At this point, the processing of file directory is completed.=========================

        /*
            4.Using ServletFileUpload to process uploaded files
              ServletFileUpload Object is responsible for handling the uploaded file and encapsulating the file as a FileItem object.
              The DiskFileItemFactory object needs to be passed in when the request is resolved using the ServletFileUpload object.
         */

        //4.1 get ServletFileUpload object
        //    (need to pass in factory object (file directory processed in step 3))
        ServletFileUpload fileUpload = new ServletFileUpload(factory);

        //4.2 upload progress of monitoring files
        fileUpload.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 pItem) {
                System.out.println("Total file size"+pContentLength+"Uploaded"+pBytesRead);
            }
        });

        //4.3 dealing with disorderly code
        fileUpload.setHeaderEncoding("UTF-8");

        //4.4 set the maximum value of uploaded single file, unit: bit
        fileUpload.setFileSizeMax(1024*1024*10);

        //4.5 set the maximum value of uploading multiple files (the total size of files that can be uploaded)
        fileUpload.setSizeMax(1024*1024*100);

        //4.6 parse the front-end request and encapsulate it as a FileItem object
        /*
            FileItem Object: use the parseRequest(Request) method of the ServletFileUpload object
            You can encapsulate the data submitted by each HTML tag in the form into a FileItem object.
            It is then returned as a List.

         */
        try {
            List<FileItem> fileItems = fileUpload.parseRequest(req);
            for (FileItem fileItem : fileItems) {
                 //Forms with files also have form items that are not files, such as the username in this case, which is the text property.
                //isFormField(); determine whether the uploaded file is a normal form or a form with files
                if (fileItem.isFormField()){   
                    //The getFieldName method returns the value of the form label name property.
                    String name = fileItem.getFieldName();
                    //The getString method is used to return the data flow content saved in the FileItem object as a string
                    String value = fileItem.getString("UTF-8");
                    System.out.println(name+":"+value);
                } else{
                    //The getName method is used to get the file name in the file upload field.
                    String uploadFileName = fileItem.getName();
                    System.out.println(""+uploadFileName);

                    if (uploadFileName.trim().equals("")||uploadFileName==null){
                        continue;//The filename does not exist or is an empty string and cannot be saved
                    }


                    //To obtain the uploaded file name, assume that the path of the file is / xxx/xxx/xxx.jpg when you choose to upload the file.
                    String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);

                    //Get the suffix of the file
                     /*
                        Get the application of file suffix name:
                        If the file suffix is not the file type required by the website, you can return directly.
                        Then notify the user that the file type is incorrect
                    */
                    String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);

                    System.out.println("The uploaded files are:"+fileName+" File type:"+fileExtName);


                    /*
                        In order to ensure the unique use of UUID (unique identification common code) for file pathnames, date differentiation can also be used
                        UUID.randomUUID(); Random generation of a unique universal code
                     */
                    //Path name of the created file
                    String uuidPathName = UUID.randomUUID().toString();


                    //====================At this point, file processing is complete=====================

                    /*
                        5. Create a storage directory for each file
                     */

                    //Create a directory for each file.
                    //The file will be stored in the uuidPathName directory under the uploadPath directory
                    String realPath = uploadPath+"/"+uuidPathName;
                    File realPathFile = new File(realPath);
                    if (!realPathFile.exists()){
                        realPathFile.mkdir();
                    }

                    //=======================Now, save the file.===================

                    /*
                        6. Transfer file content
                     */
                    //6.1 get the stream of the uploaded file (read the content of the file)
                    InputStream inputStream = fileItem.getInputStream();

                    //6.2 create file output stream (write file content)
                    FileOutputStream outputStream = new FileOutputStream(realPath+"/"+fileName);

                    //6.3 create a buffer
                    byte[] buffer = new byte[1024*8];

                    //6.4 judge whether the reading is completed. If len is greater than 0, it means that the data transmission is not completed.
                    int len = 0;
                    if ((len=inputStream.read(buffer))>0){
                        outputStream.write(buffer,0,len);
                    }

                    //6.5 shut down flow
                    inputStream.close();
                    outputStream.close();

                    //6.6 removal of temporary documents
                    fileItem.delete();
                    
                    //=======================At this point, the file transfer is complete===================
                    
                    /*
                    	7. Return upload results
                    */
                    req.setAttribute("msg","Upload succeeded!");
                    req.getRequestDispatcher("info.jsp").forward(req,resp);


                }
            }

        } catch (FileUploadException e) {
            e.printStackTrace();
            req.setAttribute("msg","Upload failed!");
            req.getRequestDispatcher("info.jsp").forward(req,resp);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            req.setAttribute("msg","Upload failed!");
            req.getRequestDispatcher("info.jsp").forward(req,resp);
        } catch (IOException e) {
            e.printStackTrace();
            req.setAttribute("msg","Upload failed!");
            req.getRequestDispatcher("info.jsp").forward(req,resp);
        }
    }
}

Source code of upload.jsp:

<body>
<%--
    Precautions for uploading files
        1.method Must be post,get Unable to get big data
        2.enctype="multipart/form-data Indicates that there is data upload in the form
--%>
<div>
    <form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post">
        <p>User name:<input type="text" name="username"></p>
        <p>Select File:<input type="file" name="file"></p>
        <p><input type="submit" value="Upload files"></p>
    </form>
</div>

</body>
</html>

info.jsp source code:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Prompt information</title>
</head>
<body>
    ${pageContext.request.getAttribute("msg")}
</body>
</html>

web.xml source code:

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

02 results display

Upload file page:

Response message:

Console print information:

03 error summary

Error 1: in upload.jsp, I forgot to type the form submission method=post, which led to the non file form recognition logic (i.e. step 1) in the servlet processing.

Error 2: in the code to get the filename, in the lastIndexOf() method, the parameter passed in was incorrectly written as ". + 1", resulting in the failure to get the filename.

Error 3: in the process of transferring files, the input and output stream parameters are wrongly written, and the file object is spliced as a file path, resulting in the absence of a file directory.

Posted by Cynix on Sun, 20 Oct 2019 12:34:23 -0700