Several ways of file upload

File upload

Front end submission method:

  1. The request method is post: < form action = "uploadServlet" method = "post" / >
  2. Form fields using file: < input type = "file" name = "file" / >
  3. Encoding method of multipart / form data request: < form action = "uploadServlet" method = "post" enctype = "multipart / form data" / >
< form action="uploadServlet" method="post" enctype="multipart/form-data">
    File: < input type="file" name="file"/>
    < input type="submit" value="Submit"/>
 </ form>

Method 1: HttpServlet of JavaWeb

  1. Commons-fileupload-1.4. Is required jar ,commons-io-2.11.0. Jar. When using HttpServletRequest, you need to import the package of servlet API

    Commons fileUpload requires commons io

  2. Need to be on the web Add servlet mapping path to XML

public class FileServlet extends HttpServlet {
    @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       // File upload
       // 1. Judge whether the uploaded form is an ordinary form or a file form	
       if(!ServletFileUpload.isMultipartContent(req)){
           return ; // Terminate the program, indicating that this is an ordinary form
       }	
       // 2. Create the save path of the uploaded file. It is recommended that the file should be in the web inf directory, and the user cannot access it directly
       String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
       File file = new File(uploadPath);
       // If the directory does not exist, create this directory for the first upload
       if(!file.exists()){
           file.mkdir(); // Create directory
       }
       // Cache: when the uploaded file is large, it is stored in the cache file and needs to be permanently saved before it is transferred to the upload folder
  
       /**File upload is usually handled by streaming,
        * Here, the components provided by apache are used to implement common file upload
        * */
       // 3. Get the DiskFileItemFactory object and process the path or size limit of file upload. There is a default
       DiskFileItemFactory factory = new DiskFileItemFactory();
       //4. Get ServletFileUpload
       ServletFileUpload upload = new ServletFileUpload(factory);
       // 5. Process uploaded files
           //The front-end request is parsed and encapsulated into a FileItem object, which needs to be obtained from the ServletFileUpload object
       try {
           List<FileItem> fileItems = upload.parseRequest(req);
           // Traverse each FileItem, and each input in the form is encapsulated into a FileItem object
           for (FileItem fileItem : fileItems) {
               // Determine whether it is a common type and the items in the form
               if (fileItem.isFormField()){
                   // Common type
  
               }else {
                   //file type
                   // Get the path to the uploaded file, and then get the file name
                   String filePath = fileItem.getName();
                   String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
                   // Get the new file name through uuid+fileName
                   String newFileName = UUID.randomUUID().toString() + fileName;
  
                   // Get the stream of FileItem
                   InputStream in = fileItem.getInputStream();
  
                   // Copy files to the server
                   String newFilePath = uploadPath+"/" + newFileName;
                       FileOutputStream out = new FileOutputStream(newFilePath);
  
                   byte[] buffer = new byte[1024];
                   int len;
                   while ((len = in.read(buffer)) != -1){
                       out.write(buffer,0,len);
                   }
  
                   // Close the resource and clear the cache of fileItem
                   out.close();
                   in.close();
  
                   fileItem.delete();
               }
           }
       } catch (FileUploadException e) {
           e.printStackTrace();
       }
   }
}

MultipartResolver is an interface. Its implementation class is shown in the figure below. It is divided into CommonsMultipartResolver class and StandardServletMultipartResolver class

Method 2: CommonsMultipartResolver

File upload based on Apache fileupload (understand)

In the web phase, we use the Apache fileupload component to realize the upload. It is encapsulated in spring MVC, which is more convenient for us to use, but the bottom layer is still implemented by Apache fileupload.

  1. Commons-fileupload-1.4. Is required jar ,commons-io-2.11.0. jar

    Commons fileUpload requires commons io

  2. The name of the bean that configures the multipartresolver processor (file upload parser) must be: multipartresolver

<!-- SpringMVC Configuration is required when uploading files MultipartResolver processor -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8" />
        <property name="maxUploadSize" value="10485760000" />
        <property name="maxInMemorySize" value="40960" />
    </bean>

How HttpServletRequest is parsed

@RequestMapping(value = "/addproduct", method = RequestMethod.POST)
@ResponseBody
private Map<String, Object> addProduct(HttpServletRequest request) {
  Map<String, Object> modelMap = new HashMap<String, Object>();
  //Accept the initialization of variables of front-end parameters, including commodity, thumbnail, detail drawing list and entity class
  ObjectMapper mapper = new ObjectMapper();
  Product product = null;
  String productStr = HttpServiceRequestUtil.getString(request, "productStr");
  MultipartHttpServletRequest multipartRequest = null;
  ImageHolder thumbnail = null;
  List<ImageHolder> productImgList = new ArrayList<ImageHolder>();
  //General purpose parser
  CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
  try {
      //If there is a file stream in the request, the relevant files (including thumbnails and detail drawings) are taken out
      //isMutipart is used to determine whether a file has been uploaded
      if (multipartResolver.isMultipart(request)) {
          multipartRequest = (MultipartHttpServletRequest) request;
          //Take out the thumbnail and build the ImageHolder object
          CommonsMultipartFile thumbnailFile = (CommonsMultipartFile) multipartRequest.getFile("thumbnail");
          thumbnail = new ImageHolder(thumbnailFile.getOriginalFilename(), thumbnailFile.getInputStream());
          //Take out the detailed picture list and build a list < imageholder > list object, which supports uploading up to six pictures
          for (int i = 0; i < IMAGEMAXCOUNT; i++) {
              CommonsMultipartFile productImgFile = (CommonsMultipartFile) multipartRequest.getFile("productImg" + i);
              if (productImgFile != null) {
                  ImageHolder productImg = new ImageHolder(productImgFile.getOriginalFilename(), productImgFile.getInputStream());
                  productImgList.add(productImg);
              } else {
                  //If the i-th detail picture file stream is empty, the loop is terminated
                  break;
              }
          }
      } else {
          modelMap.put("success", false);
          modelMap.put("errMsg", "Uploaded picture cannot be empty");
          return modelMap;
      }
  } catch (Exception e) {
      modelMap.put("success", false);
      modelMap.put("errMsg", e.toString());
      return modelMap;
  }
}

Upload of crazy God file input and output:

@Controller
public class FileController {
    //@RequestParam("file") encapsulates the file obtained by the name=file control into a CommonsMultipartFile object
    //If you upload CommonsMultipartFile in batch, it can be an array
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {

        //Get file name: file getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();

        //If the file name is empty, go back to the home page directly!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("Upload file name : "+uploadFileName);

        //Upload path save settings
        String path = request.getServletContext().getRealPath("/upload");
        //If the path does not exist, create one
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("Upload file storage address:"+realPath);

        InputStream is = file.getInputStream(); //File input stream
        OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //File output stream

        //Read write
        int len=0;
        byte[] buffer = new byte[1024];
        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }
}

Upload in transferTo():

/*
 * Use file To save the uploaded file
 */
@RequestMapping("/upload2")
public String  fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {

    //Upload path save settings
    String path = request.getServletContext().getRealPath("/upload");
    File realPath = new File(path);
    if (!realPath.exists()){
        realPath.mkdir();
    }
    //Upload file address
    System.out.println("Upload file storage address:"+realPath);

    //Write the file directly through the CommonsMultipartFile method (note this time)
    file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));

    return "redirect:/index.jsp";
}

Method 3: StandardServletMultipartResolver

Based on servlet 3 Upload files above 0

  1. Need to rely on servlet3 Version above 0

  2. The name of the bean that configures the multipartresolver processor (file upload parser) must be: multipartresolver

    <bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>
    
  3. Conreoller

@RequestMapping("/upload")
public Result<?> upload(MultipartFile file, HttpServletRequest request) throws IllegalStateException, IOException {
        Result<Object> result = new Result<>();
        result.setSuccess(false);
        //Check whether the file is empty
        if (file.isEmpty()) {
            result.setMessage("The uploaded file cannot be empty");
            return result;
        }
		//Check file size 2097152 =2M
		if(file.getSize() > 2097152) {
            result.setMessage("File greater than 2 M");
            return result;
		}
		//Check if it is a picture
		try {
			BufferedImage bi = ImageIO.read(file.getInputStream());
			if(bi == null){
                result.setMessage("Not a picture");
            	return result;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
        // Obtain the file storage path (absolute path). In actual development, it is recommended to directly use the absolute address of a server
        String path = request.getServletContext().getRealPath("/WEB-INF/upload/");
//        System.out.println("relative / WEB-INF/upload / full path in the server:" + path);
        //Get the suffix of the uploaded file
//        System.out.println("file name uploaded by the client:" + file.getOriginalFilename());
        String originalFilename = file.getOriginalFilename();
        String suff = originalFilename.substring(originalFilename.lastIndexOf("."));
        // Get file name
        String fileName = UUID.randomUUID().toString().replaceAll("-","")+suff;
        // Create file instance
        File filePath = new File(path, fileName);
        // If the file directory does not exist, create a directory
        if (!filePath.getParentFile().exists()) {
            filePath.getParentFile().mkdirs();
            System.out.println("Create directory" + filePath);
        }
        // write file
        file.transferTo(filePath);

        result.setMessage("Upload succeeded");
        result.setCode(200);
        result.setSuccess(true);
        return result;
    }

Note: if the name of the front-end file upload control is inconsistent with the parameter name of the processor method, you can use the annotation @ RequestPart("parameter name") or @ RequestParam("parameter name")

@RequestPart has the same meaning and effect as @ RequestParam in file upload (based on form file upload) without separation of front and back ends

@RequestPart can handle special data formats, such as JSON

Consistent: (recommended method in actual development)

//front end:
<input type="file" name="file">
//Back end:
public String upload(MultipartFile file, HttpServletRequest request){}

If inconsistent:

//front end:
<input type="file" name="uploadFile">
//Back end:
public String upload(@RequestParam("uploadFile") MultipartFile file, ....){}
//or
public String upload(@RequestPart("uploadFile") MultipartFile file, ....){}

Multi file upload

For multi file upload, you only need to set multiple < input type = "file" name = "file" > name attributes in the html code to the same. Then use the MultipartFile array in the controller to accept.

@RequestMapping(value="/upload", method=RequestMethod.POST)
public String fileUpload(@RequestParam("file") MultipartFile[] file){
   //Traversal array single upload
    for (MultipartFile multipartFile : file) {
        
    }
}

Add: if you want to limit the file upload type

Solution:

1) Limit file types based on the front end

2) Based on the back end, it is recommended to use the interceptor of spring MVC framework for interception verification

Keywords: Java

Added by JaneDoe on Tue, 04 Jan 2022 20:54:41 +0200