Implementation of SpringMVC file upload function


1. SpringMVC file upload

SpringMVC provides good support for file uploads. In Springboot, only a simple configuration is required to complete the file upload function. In SpringMVC, DispatcherServlet converts HttpServletRequest into MultipartHttpServletRequest object through adapter mode . The MultipartHttpServletRequest interface extends all methods of the HttpServletRequest interface and the MultipartRequest interface, and customizes some methods for operating files, so that file uploads can be realized through these methods.

public interface MultipartHttpServletRequest extends HttpServletRequest, MultipartRequest {
    
    

	/**
	 * Return this request's method as a convenient HttpMethod instance.
	 */
	@Nullable
	HttpMethod getRequestMethod();

	/**
	 * Return this request's headers as a convenient HttpHeaders instance.
	 */
	HttpHeaders getRequestHeaders();

	/**
	 * Return the headers for the specified part of the multipart request.
	 * <p>If the underlying implementation supports access to part headers,
	 * then all headers are returned. Otherwise, e.g. for a file upload, the
	 * returned headers may expose a 'Content-Type' if available.
	 */
	@Nullable
	HttpHeaders getMultipartHeaders(String paramOrFileName);

}

The general relationship between HttpServletReuqes t and MultipartHttpServletRequest is shown in the figure:
insert image description here


Two, SpringBoot configuration file upload

When using SpringMVC to upload files, you also need to configure MultipartHttpServletRequest , and this task is implemented through the MultipartResolver interface. In the Springboot mechanism, if you do not configure a MultipartResolver object, springboot will automatically create a MultipartResolver object for you, which is actually a StandardServletMultipartResolver . Commonly used file configuration items are as follows:

#是否起开SpringMVC上传功能
spring.servlet.multipart.enabled=true
#指定默认上传的文件夹
spring.servlet.multipart.location=
#指定默认上传单个文件大小(默认是1MB)
spring.servlet.multipart.max-file-size=1MB
#指定所有文件总共大小(默认是10MB)
spring.servlet.multipart.max-request-size=10MB

3. Common exceptions in uploading SpringBoot configuration files

1. java.lang.IllegalStateException: Unable to process parts as no multi-part configuration has been provided

This exception is usually caused by turning off the SpringMVC file upload function. Change the springboot configuration to: spring.servlet.multipart.enabled=true (enable the file upload function).

2. FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.

This error is the most common, because the default single file upload size of SpringMVC file upload is 1MB, which is 1048576 bytes. At this time, it should be that the file you upload exceeds 1MB. You only need to increase the size of SpringMVC to support a single file upload. spring.servlet.multipart.max-file-size=?MB.

3. SizeLimitExceededException: the request was rejected because its size (xxxx) exceeds the configured maximum (xxxx)

This error is that the total size of a single request file upload exceeds the total size of SpirngMVC file uploads. The total size defaults to 10MB, which can be modified by spring.servlet.multipart.max-request-size=?MB.


4. SpringBoot implements file upload function

Through the above brief introduction, let us now implement a SpringBoot file upload function. First, I configured SpringMVC with a single file upload file size of 10MB and a single request upload file size of 100MB, and enabled the SpringMVC file upload function.

spring:
  servlet:
    multipart:
    # 是否开启springMVC 多部分上传功能(默认开启)
      enabled: true
    # 上传单个文件大小(默认是1MB)
      max-file-size: 10MB
    # 限制所有文件大小
      max-request-size: 100MB

1. Use MultipartFile to realize file upload.

The MultipartFile interface has nothing to do with the MultipartHttpServletRequest interface, but the implementation class of the MultipartFile interface, StandardMultipartFile , is a static internal class of StandardMultipartHttpServletRequest , so you can use MultipartFile to implement file uploads. For specific implementation, see the source code of the StandardMultipartHttpServletRequest class. It is also very simple to use, the code is as follows:

    @RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public void uploadFile(@RequestParam(value = "file") MultipartFile multipartFile) throws IOException {
    
    
        //获取上传文件名称
        String fileName = multipartFile.getOriginalFilename();
        //获取上传文件类型
        String contentType = multipartFile.getContentType();
        //获取上传文件输入流,便于文件内容读写操作
        InputStream inputStream = multipartFile.getInputStream();
        System.out.println("fileName = " + fileName + ", contentType = " + contentType);
    }

Use @RequestParam to convert the parameter named file into a MultipartFile object, and then you can get the file name through the getOriginalFilename method, the getContentType method to get the file type, and the getInputStream method to get an input stream, and then you can operate on the file. Using PostMan test:
insert image description here
Console input results:
insert image description here
For MultipartFile to realize file upload, you can refer to the StandardMultipartHttpServletRequest source code, which will not be described too much here.


2. Use MultipartHttpServletRequest to realize file upload (recommended).

By default, Spring recommends using StandardMultipartHttpServletRequest , which is also the implementation class of the MultipartHttpServletRequest interface. The file upload process is mainly implemented in StandardMultipartHttpServletRequest . StandardMultipartHttpServletRequest can handle multiple file uploads at one time, and does not need to specify parameter names like MultipartFile . Conventional usage is as follows:

    @RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public void uploadFile(HttpServletRequest request) throws IOException {
    
    

        // 强制将HttpServletRequest转为MultipartHttpServletRequest
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        //获取指定MultipartFile文件
        MultipartFile file = multipartRequest.getFile("java");
        //获取文件名称
        String originalFilename = file.getOriginalFilename();
        //保存上传文件到xxx路径
        file.transferTo(Paths.get("xxx"));

        //不指定上传文件参数,而是获取整个上传文件集合
        MultiValueMap<String, MultipartFile> multiFileMap = multipartRequest.getMultiFileMap();
        //遍历整个上传文件集合,获取上传文件
        Iterator<String> MultipartFileIterator = multiFileMap.keySet().iterator();
        while (MultipartFileIterator.hasNext()) {
    
    
            String key = MultipartFileIterator.next();
            //这里是集合的原因是,可能一个参数上传多个文件。
            List<MultipartFile> multipartFiles = multiFileMap.get(key);
            System.out.println("当前上传文件参数: " + key);
            multipartFiles.forEach(multipartFile -> {
    
    
                System.out.println("上传文件名称: " + multipartFile.getOriginalFilename() + ", 上传文件类型:" + multipartFile.getContentType());
            });
            System.out.println("------------分割----------");
        }
    }

Using PostMan to send 4 files, two are java and two are docker. The control input results are as follows:
insert image description here
Console print results:
insert image description here
These are probably the two most common ways of uploading files in SpringMVC. MultipartHttpServletRequest has more operable methods, and it is more convenient to process multiple files uploading at the same time. MultipartFile is suitable for uploading a single file. Both of them have their own advantages, so you can choose according to your own situation.


Guess you like

Origin blog.csdn.net/qq_43600166/article/details/125288005