SpringBoot文件上传 MultipartAutoConfiguration源码简单解析

SpringBoot中文件上传
老样子,先上代码,再源码分析

SpringBoot里自动装配了MultipartResolver
所以这样我们可以不用加依赖

文件上传类

@RestController
public class UploadController {
    SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
    @PostMapping("/upload")
    public String upload(MultipartFile file, HttpServletRequest req) throws IOException {
        String format = sdf.format(new Date());
        String realPath = req.getServletContext().getRealPath("/img") + format;
        File folder = new File(realPath);
        if (!folder.exists()) {
            folder.mkdirs();
        }

        String oldName = file.getOriginalFilename();
        String newNamme = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
            file.transferTo(new File(folder, newNamme));
            String url = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/img" + format + newNamme;
            return url;


    }
}

这里需要讲一下的是req.getServletContext().getRealPath("/")
是默认是从你项目所在的路径,也就是得到的就是你tomcat下webapps下的项目根路径,然后/img就在这个文件夹下,如果没有就会创建。

前端类似这样的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="上传">
</form>
</body>
</html>

或者这样的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="jquery3.3.1.js"></script>
</head>
<body>
<div id="result"></div>
<input type="file" id="file">
<input type="button" value="上传" onclick="fileupload()">
<script>
    function fileupload() {
        var file = $("#file")[0].files [0];
        var formData = new FormData();
        formData.append("file", file);
        $.ajax({
            type: 'post',
            url: '/upload',
            data: formData,
            processData:false,
            contentType:false,
            success:function (msg) {
                $("#result").html(msg);
            }
        })
    }
</script>
</body>
</html>

设置文件上传的大小, 因为springboot内置tomact的的文件传输默认为1MB

#配置文件传输
spring.servlet.multipart.enabled =true  
spring.servlet.multipart.file-size-threshold =0
#单个数据的大小
spring.servlet.multipart.max-file-size = 100Mb
#总数据的大小
spring.servlet.multipart.max-request-size=100Mb

也可以自定义配置类

/**
 * 配置上传文件大小的配置
 * @return
 */
@Bean
public MultipartConfigElement multipartConfigElement() {
   MultipartConfigFactory factory = new MultipartConfigFactory();
   //  单个数据大小
   factory.setMaxFileSize("102400KB");
   /// 总上传数据大小
   factory.setMaxRequestSize("102400KB");
   return factory.createMultipartConfig();
}

还可以设置tomcat的文件限制大小
在这里插入图片描述

上传文件文件过大时出现如下错误:

org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field pic exceeds its maximum permitted size of 1048576 bytes.

那么为什么可以不用加上文件上传所需依赖了?

答案和以前一样,就是SpringBoot里面有自动装配类
MultipartAutoConfiguration

从启动类注解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

而这个spring.factories的路径:

org\springframework\boot\spring-boot-autoconfigure\2.1.6.RELEASE\spring-boot-autoconfigure-2.1.6.RELEASE-sources.jar!\META-INF\spring.factories

@EnableAutoConfiguration 表示启用 Spring 应用程序上下文的自动配置,该注解会自动导入一个名为 AutoConfigurationImportSelector 的类,而这个类会去读取一个名为 spring.factories 的文件, spring.factories 中则定义需要加载的自动化配置类
在这里插入图片描述
在这里插入图片描述

@Configuration
@ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class })
@ConditionalOnProperty(prefix = "spring.servlet.multipart", name = "enabled", matchIfMissing = true)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(MultipartProperties.class)
public class MultipartAutoConfiguration {

   private final MultipartProperties multipartProperties;

   public MultipartAutoConfiguration(MultipartProperties multipartProperties) {
      this.multipartProperties = multipartProperties;
   }

   @Bean
   @ConditionalOnMissingBean({ MultipartConfigElement.class, CommonsMultipartResolver.class })
   public MultipartConfigElement multipartConfigElement() {
      return this.multipartProperties.createMultipartConfig();
   }

   @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
   @ConditionalOnMissingBean(MultipartResolver.class)
   public StandardServletMultipartResolver multipartResolver() {
      StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
      multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
      return multipartResolver;
   }

}

@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
@ConditionalOnMissingBean(MultipartResolver.class)
public StandardServletMultipartResolver multipartResolver() {
   StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
   multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
   return multipartResolver;
}

  1. @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
    注册bean到Spring容器,name为在DispatcherServlet里的文件上传解析器初始化时的bean名

  2. @ConditionalOnMissingBean(MultipartResolver.class)
    如果没有MultipartResolver这个bean就默认使用StandardServletMultipartResolver。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

偷偷学习被我发现

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值