首先我们要知道什么是Spring Boot,这里简单说一下,Spring Boot可以看作是一个框架中的框架--->集成了各种框架,像security、jpa、data、cloud等等,它无须关心配置可以快速启动开发,有兴趣可以了解下自动化配置实现原理,本质上是 spring 4.0的条件化配置实现,深抛下注解,就会看到了。

  说Spring Boot 文件上传原理 其实就是Spring MVC,因为这部分工作是Spring MVC做的而不是Spring Boot,那么,SpringMVC又是怎么处理文件上传这个过程的呢?

  图:

  首先项目启动相关配置,再执行上述第二步的时候 DispatcherServlet会去查找id为multipartResolver的Bean,在配置中看到Bean指向的是CommonsMultipartResolve,其中实现了MultipartResolver接口。

  第四步骤这里会判断是否multipart文件即isMultipart方法,返回true:就会调用 multipartResolver 方法,传递HttpServletRequest会返回一个MultipartHttpServletRequest对象,再有DispatcherServlet进行处理到Controller层;返回false:会忽略掉,继续传递HttpServletRequest。

  在MVC中需要在配置文件webApplicationContext.xml中配置 如下:

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="defaultEncoding" value="UTF-8"/>
            <property name="maxUploadSize" value="100000000"/>
            <property name="uploadTempDir" value="fileUpload/temp"/>
    </bean>

  而Spring Boot已经自动配置好,直接用就行,做个test没什么问题。有默认的上传限制大小,不过在实际开发中我们还是做一些配置的,

如下在application.properties中:

# multipart config
#默认支持文件上传 spring.http.multipart.enabled=true
#文件上传目录 spring.http.multipart.location=/tmp/xunwu/images/
#最大支持文件大小 spring.http.multipart.max-file-size=4Mb
#最大支持请求大小 spring.http.multipart.max-request-size=20MB

当然也可以写配置类来实现,具体的就不做展示了。

  看完上述你肯定有个大概的了解了,这里再啰嗦下,Spring提供Multipart的解析器:MultipartResolver,上述说的是CommonsMultipartResolver,它是基于Commons File Upload第三方来实现,这也是在Servlet3.0之前的东西,3.0+之后也可以不需要依赖第三方库,可以用StandardServletMultipartResolver,同样也是实现了MultipartResolver接口,我们可以看下它的实现:

 * Copyright 2002-2017 the original author or authors.

package org.springframework.web.multipart.support;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;

import org.apache.commons.logging.LogFactory;

import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;

/**
 * Standard implementation of the {@link MultipartResolver} interface,
 * based on the Servlet 3.0 {@link javax.servlet.http.Part} API.
 * To be added as "multipartResolver" bean to a Spring DispatcherServlet context,
 * without any extra configuration at the bean level (see below).
 *
 * <p><b>Note:</b> In order to use Servlet 3.0 based multipart parsing,
 * you need to mark the affected servlet with a "multipart-config" section in
 * {@code web.xml}, or with a {@link javax.servlet.MultipartConfigElement}
 * in programmatic servlet registration, or (in case of a custom servlet class)
 * possibly with a {@link javax.servlet.annotation.MultipartConfig} annotation
 * on your servlet class. Configuration settings such as maximum sizes or
 * storage locations need to be applied at that servlet registration level;
 * Servlet 3.0 does not allow for them to be set at the MultipartResolver level.
 *
 * @author Juergen Hoeller
 * @since 3.1
 * @see #setResolveLazily
 * @see HttpServletRequest#getParts()
 * @see org.springframework.web.multipart.commons.CommonsMultipartResolver
 */
public class StandardServletMultipartResolver implements MultipartResolver {

    private boolean resolveLazily = false;

    /**
     * Set whether to resolve the multipart request lazily at the time of
     * file or parameter access.
     * <p>Default is "false", resolving the multipart elements immediately, throwing
     * corresponding exceptions at the time of the {@link #resolveMultipart} call.
     * Switch this to "true" for lazy multipart parsing, throwing parse exceptions
     * once the application attempts to obtain multipart files or parameters.
     */
    public void setResolveLazily(boolean resolveLazily) {
        this.resolveLazily = resolveLazily;
    }

    @Override
    public boolean isMultipart(HttpServletRequest request) {
        // Same check as in Commons FileUpload...
        if (!"post".equals(request.getMethod().toLowerCase())) {
            return false;
        }
        String contentType = request.getContentType();
        return (contentType != null && contentType.toLowerCase().startsWith("multipart/"));
    }

    @Override
    public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
        return new StandardMultipartHttpServletRequest(request, this.resolveLazily);
    }

    @Override
    public void cleanupMultipart(MultipartHttpServletRequest request) {
        // To be on the safe side: explicitly delete the parts,
        // but only actual file parts (for Resin compatibility)
        try {
            for (Part part : request.getParts()) {
                if (request.getFile(part.getName()) != null) {
                    part.delete();
                }
            }
        }
        catch (Throwable ex) {
            LogFactory.getLog(getClass()).warn("Failed to perform cleanup of multipart items", ex);
        }
    }

}

这里是之前写的test的后者实现配置类,可以简单看下,作为了解:

package com.bj.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.web.MultipartProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.MultipartConfigElement;

@Configuration
@EnableConfigurationProperties(MultipartProperties.class)
public class FileUploadConfig {

    private final MultipartProperties multipartProperties;

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

    /**
     * 注册解析器
     * @return
     */
    @Bean(name= DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
    @ConditionalOnMissingBean(MultipartResolver.class)
    public StandardServletMultipartResolver multipartResolver(){
        StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
        multipartResolver.setResolveLazily(multipartProperties.isResolveLazily());
        return multipartResolver;
    }

    /**
     * 上传配置
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public MultipartConfigElement multipartConfigElement(){
        return this.multipartProperties.createMultipartConfig();
    }

}

Spring Boot 文件上传原理的更多相关文章

  1. spring boot文件上传、下载

    主题:Spring boot 文件上传(多文件上传)[从零开始学Spring Boot]http://www.iteye.com/topic/1143595 Spring MVC实现文件下载http: ...

  2. Spring Boot 文件上传

    其实网上已经有很多这样的文章了.为什么我还要记录一下呢?原因是在工作中对接外系统时,碰到了他们调取我们文件上传接口确存在着http请求头部规范的情况,从而导致用传统方法获取不到参数.今天就来整理下Sp ...

  3. spring boot 文件上传大小限制

    错误信息 : Spring Boot:The field file exceeds its maximum permitted size of 1048576 bytes. 解决方法一:在启动类添加如 ...

  4. 从.Net到Java学习第十篇——Spring Boot文件上传和下载

    从.Net到Java学习系列目录 图片上传 Spring Boot中的文件上传就是Spring MVC中的文件上传,将其集成进来了. 在模板目录创建一个新的页面 profile/uploadPage. ...

  5. Spring Boot 文件上传与下载

    原文地址: https://www.cnblogs.com/studyDetail/p/7003253.html 1.在pom.xml文件中添加依赖 <project xmlns="h ...

  6. (29)Spring boot 文件上传(多文件上传)【从零开始学Spring Boot】

    文件上传主要分以下几个步骤: (1)新建maven java project: (2)在pom.xml加入相应依赖: (3)新建一个表单页面(这里使用thymleaf); (4)编写controlle ...

  7. spring boot 文件上传工具类(bug 已修改)

    以前的文件上传都是之前前辈写的,现在自己来写一个,大家可以看看,有什么问题可以在评论中提出来. 写的这个文件上传是在spring boot 2.0中测试的,测试了,可以正常上传,下面贴代码 第一步:引 ...

  8. Spring Boot 文件上传简易教程

    上传文件是我们日常使用最为广泛的功能之一,比如App端上传头像.本章演示如何从客户端上传到 Spring Boot 开发的 Api中. 本项目源码 github 下载 1 新建 Spring Boot ...

  9. Spring Boot文件上传

    一.创建一个简单的包含WEB依赖的SpringBoot项目 二.配置文件上传的文件大小限制 # 上传文件总的最大值spring.servlet.multipart.max-request-size=1 ...

随机推荐

  1. maven的安装与配置使用

     一  maven的安装 1 在镜像(https://mirrors.tuna.tsinghua.edu.cn/apache/)中下载指定的版本(注意,Maven 版本与IDE版本应保持匹配). 2 ...

  2. Windows Server 2016-重置目录还原模式密码

    目录还原模式:Directory Services Restore Mode,简称DSRM,又称目录服务恢复模式.是Windows域控制器的服务器安全模式启动选项.DSRM允许管理员用来修复或还原修复 ...

  3. 网卡name-eth1如何修改为eth0

    正常来说,Linux在识别网卡时第一张会是eth0,第二张才是eth1. 有时候我们使用虚拟机克隆技术后网卡的信息就会改变,新克隆出来的虚拟主机网卡名字可能变为eth1.无论我们怎么修改都无法改变,这 ...

  4. web端表格测试用例

    表格测试: 表格内容列表排序功能是否正常每一栏的宽度是否足够宽,表格里的文字是否都有折行?是否有因为某一格的内容太多,而将整行的内容拉长?表格是否能左(右)添加(删除)列,表格是否能上(下)添加(删除 ...

  5. Yii2 场景

    下面给大家介绍一下 yii2.0 场景的使用. 现在在 post表里面有 title image content 三个的字段,当我创建一个 post 的时候,我想三个字段全部是必填项,但是你修改的时候 ...

  6. wamp server环境下mysql数据库的密码为什么修改不了?

    每次这个控制台,不输入密码可以直接用,用root登录都登录不了.修改root密码也修改不了.困惑? 经过不断的尝试终于找到解决的办法: 1,在mysql的配置文件my.ini的末尾添加 skip-gr ...

  7. POJ - 1860 Bellman-Ford判正环

    心累,陕西邀请赛学校不支持,可能要自费了.. 思路:套用Bellman-Ford判断负环的思路,把大于改成小于即可判定是否存在从源点能到达的正环.如果存在正环,那么完全多跑几次正环就可以把钱增加到足够 ...

  8. 关于VS2013调试IIS应用源代码时无法进入断点的问题总结

    调试无法进入断点 前言:今天再次遇到之前调试无法进入断点的问题,本来想不写呢觉得没什么只是又犯了同样的错误,但是我发现这个问题我分析起来还是挺费劲的,我仔细想了想原因, 是因为自己对之前的错误没有进行 ...

  9. shell脚本 awk工具

    awk工具概述awk编程语言/数据处理引擎基于模式匹配检查输入文本,逐行处理并输出通常在shell脚本中,或取指定的数据单独用时,可对文本数据做统计 命令格式格式一:awk [选项] '[条件]{编辑 ...

  10. 工业级GBDT算法︱微软开源 的LightGBM(R包正在开发....)

    看完一篇介绍文章后,第一个直觉就是这算法已经配得上工业级属性.日前看到微软已经公开了这一算法,而且已经发开python版本,本人觉得等hadoop+Spark这些平台配齐之后,就可以大规模宣传啦~如果 ...