/ SpringBoot

Spring Boot 文件上传

通过 MultipartFile 来处理文件上传:

public String handleFormUpload(String name,MultipartFile file) throws IOException {
    if(!file.isEmpty){
        String fileName = file.getOriginalFilename();
        InputStream ins = file.getInputStream();
        
        // ...
        
        return "success";
    }
    return "failure";
}

MultipartFile 提供了一下方法来获取上传文件的信息。

  1. getOriginalFilename 获取上传文件的名字。
  2. getBytes 获取上传文件内容,转为字节数组。
  3. getInputStream 获取一个 InputStream
  4. isEmpty 上传文件内容为空,或者就没有文件上传
  5. getSize 文件上传的大小
  6. transferTo(File dest)保存上传文件到目标文件系统。

在 HTML 前端的代码

<form enctype="multipart/form-data" method="POST">
    <input type="file" multiple="multiple" name="file">
</form>

可以通过配置文件 application.properties 对 Spring Boot 上传的文件进行限定。

spring.servlet.multipart.enabled=true
spring.servlet.multipart.file-size-threshold=0
spring.servlet.multipart.location=
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.resolve-lazily=false

参数 enabled 默认为 true,即允许附件上传。

file-size-threshold 限定了当上传的文件超过一定长度时,就先先写到临时文件里。这有助于上传文件不占用过多内存,单位时 MB 或者 KB。默认是0,不限定阈值。

location 值指的是临时文件的存放目录,如果不限定,则是 Web 服务器提供的一个临时目录。

max-file-size 属性指定了单个文件的最大长度,默认是 1 MB

max-request-size 属性说明单次 HTTP 请求上传的最大长度,默认 10 MB

通过 Ajax 来上传文件。

$.ajax({    
     url : "http://localhost:8080/STS/rest/user",    
     type : "POST",    
     data : $( '#postForm').serialize(),    
     success : function(data) {    
          $( '#serverResponse').html(data);    
     },    
     error : function(data) {    
          $( '#serverResponse').html(data.status + " : " + data.statusText + " : " + data.responseText);    
     }    
}); 

通常我们提交(使用submit button)时,会把form中的所有表格元素的name与value组成一个queryString,提交到后台。这用jQuery的方法来说,就是serialize。

通过$('#postForm').serialize()可以对form表单进行序列化,从而将form表单中的所有参数传递到服务端。

但是上述方式,只能传递一般的参数,上传文件的文件流是无法被序列化并传递的。
不过如今主流浏览器都开始支持一个叫做FormData的对象,有了这个FormData,我们就可以轻松地使用Ajax方式进行文件上传了。

使用 Form Data 来上传文件

XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件。

获取一个 FormData 对象有三种方式

  1. 创建一个空的 FormData 对象

    var formdata = new FormData()
    formdata.append("name","Yang")
    formdata.append("url","http://dowhile.net")
    
  2. 取得form元素对象,将它作为参数传入FormData对象中

var formobj =  document.getElementById("form")
var formdata = new FormData(formobj)
  1. 利用form元素对象的getFormData方法生成它
var formobj =  document.getElementById("form")
var formdata = formobj.getFormData()

FormData 对象的一些常用方法

  1. FormData.append
    本方法用于向已存在的键添加新的值,如该键不存在,新建之。
  2. FormData.delete
    将一对键和值从 FormData 对象中删除。
    formData.delete(username)
  3. FormData.get
    返回给定键的所有值
  4. FormData.has
    检查是否包含给定键,返回 true 或 false

Ajax通过FormData上传文件

<form id="uploadForm" enctype="multipart/form-data">
    <input id="file" type="file" name="file"/>
    <button id="upload" type="button">upload</button>
</form>
$.ajax({
    url: '/upload',
    type: 'POST',
    cache: false,
    data: new FormData($('#uploadForm')[0]),
    processData: false,
    contentType: false
}).done(function(res) {
}).fail(function(res) {});

这里要注意几点:

  1. processData设置为false。因为data值是FormData对象,不需要对数据做处理。
  2. 标签添加enctype="multipart/form-data"属性。
  3. cache设置为false,上传文件不需要缓存。
  4. contentType设置为false,不设置contentType值,因为是由表单构造的FormData对象,且已经声明了属性enctype="multipart/form-data",所以这里设置为false