Sprmvc file upload

Keywords: Spring Tomcat Maven xml

spring mvc file upload needs to rely on commons-io and commons-fileupload to achieve together

premise

Assuming that the dependencies, configurations, etc. on spring mvc are normal and usable, that part is not explained in this article.

rely on

Managing with maven requires dependencies that include

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>

To configure

Configuration using xml

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8" />
    <! - Set the file size allowed to upload in bytes - >
    <!-- 100MB -->
    <property name="maxUploadSize" value="104857600" />
    <property name="maxInMemorySize" value="1024" />
</bean>

If you use spring-boot, you don't need to configure it, just configure the size limit of the uploaded file.

#Upload File Size Limitation
spring.http.multipart.max-file-size = 200Mb
spring.http.multipart.max-request-size= 210Mb

Note here that in the official document of spring-boot, it is said that - 1 means no restrictions, but in actual use, it is found that setting - 1 is equivalent to no settings and does not work.

At the same time, spring boot uses its own tomcat container, which includes some APIs of commons-io and commons-fileupload in tomcat integrated version.
But it's not complete, so some APIs are not used when using it. Should we pay attention to it?

Page data submission

Originally, the code for page submission requests is beyond the scope of this article, but since you want to write a complete, then write it as well.

For uploading files, you need to use post requests, and enctype="multipart/form-data" needs to be set in the <form> attribute.

A complete < form > tag is like

<form action='/system-upgrade' method="post" enctype="multipart/form-data">
    File: <input type= "file" name= "file">
    <input type="submit" value='submit'>
</form>

In practice, it may also contain other input fields, which correspond to the controller.

Controller receives request

The controller marks the receiving post request on the corresponding method and uses MultipartFile to represent the relevant information of the uploaded file.

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

    @RequestMapping(value = "/system-upgrade", method = RequestMethod.POST)
    @ResponseBody
    public BooleanResultVO upgradeSystem(@RequestParam MultipartFile file) {
        webLogService.addAdminLog("upgrade system, upload file:" + file.getOriginalFilename());
        return new BooleanResultVO(systemService.upgrade(file));
    }

 

Document processing

In practice, it is often necessary to store files and record the names of files uploaded by users.
However, this name often contains some special symbols and may duplicate files already in the storage directory.

Here's a demonstration of how to record the name uploaded by the user while using the timestamp to store the actual file name

public Boolean uploadFile(MultipartFile file) {
    // test.mp3
    String originalName = file.getOriginalFilename();
    // test
    String showName = originalName.substring(0, originalName.lastIndexOf("."));
    // .mp3
    String subfix = originalName.substring(showName.length());
    // mp3
    String format = subfix.substring(1).toLowerCase();
    if (!("mp3".equals(format) || "wav".equals(format))) {
        logger.info("try to upload voice file failed, filename subfix:" + format);
        return Boolean.FALSE;
    }
    logger.debug("try to upload voicefile:" + originalName);

    String fileName = String.valueOf(System.currentTimeMillis());
    File destFile = new File(VoiceFile.FILE_PATH, fileName + subfix);
    try {
        file.transferTo(destFile);
    } catch (IOException e) {
        logger.error(e.toString());
        return Boolean.FALSE;
    }
    VoiceFile voiceFile = new VoiceFile();
    voiceFile.setFileName(fileName);
    voiceFile.setFileFormat(format);
    voiceFile.setShowName(showName);
    voiceFile = voiceFileDao.save(voiceFile);
    logger.info("uploaded voicefile,name:" + destFile.getName());
    return Boolean.TRUE;
}

This has a key api

  • file.getOriginalFilename() Gets the file name where the file is located by the user
  • file.transferTo(destFile) transfers a file to the specified file


Another is using file copies.

import org.apache.commons.io.FileUtils;

    String fileName = srcFile.getOriginalFilename();
    File destFile = new File(parent, fileName);
    try {
        FileUtils.copyInputStreamToFile(srcFile.getInputStream(), destFile);
    } catch (IOException e) {}

 

This approach requires exceptions to be caught, and the underlying technology is the same, but using file.transferTo(destFile) is wrapped in spring and provides space for future optimization.

Posted by aneuryzma on Fri, 28 Jun 2019 18:17:11 -0700