SpringBoot关于文件上传配置的几种方式

在进行SpringBoot项目文件临时目录位置及其最大文件传输大小等相关配置的时候,总结几种可以进行配置的方式

1、@MultipartConfig 注解

在 javax.servlet.annotation 包里有一个MultipartConfig 注解来进行文件上传的相关配置

源码:

package javax.servlet.annotation;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MultipartConfig {
    /**
     * 临时文件上传目录
     */
    String location() default "";

    /**
     * 上传文件最大值 
     */
    long maxFileSize() default -1L;

    /**
     * @return the maximum size of the request allowed for {@code
     *         multipart/form-data}
     */
    long maxRequestSize() default -1L;

    /**
     * @return the size threshold at which the file will be written to the disk
     */
    int fileSizeThreshold() default 0;
}

使用:直接在相关的Controller 上进行使用,可以写一个全局的Controller上进行使用,也可以自己写一个额外的全局Controller注解来进行使用,方法肯定

@RestController
@RequestMapping("test")
// MultipartConfig 注解的使用
@MultipartConfig(maxFileSize = 1024*1024*1024, maxRequestSize = 1024*1024*1024)
public class PackagesController
{
    @RequestMapping(method = RequestMethod.POST)
    public String create(@RequestParam("package") MultipartFile uploadedPackage)
    {
        return "create";
    }
}

2、配置文件

直接在Spring的相关yaml配置文件中进行相关属性值的指定

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nBF8rpAq-1645413754687)(C:\Users\Administrator\Desktop\sx\photo\multi_1.png)]

其他无需进行相关的配置

3、利用SpringBoot的自动配置原理

写一个文件上传属性设置相关的配置类 MultipartConfig ,以**@Configuration**进行指定,然后来进行相应属性的配置

@Configuration
public class MultipartConfig {
    /**
     * 文件上传临时路径
     */
    @Bean
    MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        String location = System.getProperty("user.home") + "/my/temp";
        File tmpFile = new File(location);
        if (!tmpFile.exists()) {
            if (!tmpFile.mkdirs()) {
                System.out.println("create was not successful.");
            }
        }
        factory.setLocation(location);
        return factory.createMultipartConfig();
    }
}

原理

这里可能有几个问题:

  • 如果我不指定文件上传的临时目录,那临时目录应该上传到哪里去了,也就是默认的临时目录是啥?
  • 这种@Configuration 让这个配置是如何生效的?

问题1:如果我不指定文件上传的临时目录,那临时目录应该上传到哪里去了,也就是默认的临时目录是啥?

private void parseParts(boolean explicit) {

    // Return immediately if the parts have already been parsed
    if (parts != null || partsParseException != null) {
        return;
    }

    Context context = getContext();
    MultipartConfigElement mce = getWrapper().getMultipartConfigElement();
	....省略
    boolean success = false;
    try {
        File location;
        String locationStr = mce.getLocation();
        // 如果不指定,locationStr是字符串
        if (locationStr == null || locationStr.length() == 0) {
            // 获取到ServletContext.TEMPDIR这个attribute的值,这个ServletContext.TEMPDIR 为 javax.servlet.context.tempdir
            // 这个属性的值可以在配置文件中指定,默认的是 tmp/tomcat.xxxxxx.端口号/work/Tomcat/localhost/ROOT
            location = ((File) context.getServletContext().getAttribute(
                    ServletContext.TEMPDIR));
        } else {
            // If relative, it is relative to TEMPDIR
            location = new File(locationStr);
            if (!location.isAbsolute()) {
                location = new File(
                        (File) context.getServletContext().getAttribute(ServletContext.TEMPDIR),
                        locationStr).getAbsoluteFile();
            }
        }
	    ... 省略代码
    } finally {
        if (partsParseException != null || !success) {
            parameters.setParseFailedReason(FailReason.UNKNOWN);
        }
    }
}

问题二:这种@Configuration 让这个配置是如何生效的?

启动Tomcat的时候会启动 StandardWrapper 进行初始化,然后会进行是否指定 multipartConfigElement bean的判断,从而来进行相应的初始化

public synchronized Servlet loadServlet() throws ServletException {
    // 如果指定了就按指定的进行初始化
    if (multipartConfigElement == null) {
        MultipartConfig annotation =
                servlet.getClass().getAnnotation(MultipartConfig.class);
        if (annotation != null) {
            multipartConfigElement =
                    new MultipartConfigElement(annotation);
        }
    }
}
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐