8、SpringMVC-文件上传

一、导包相关包

<!-- 文件上传核心包 -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>${fileupload.version}</version>
</dependency>
<!-- 工具包 -->
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>${commons-lang.version}</version>
</dependency>

二、栗子

控制层

@RestController
public class UploaderController {
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String uploadSingleFile(@RequestParam("img") MultipartFile multipartFile) throws IOException {
        String imagePath = UploadUtils.saveImage(multipartFile);
        return imagePath;
    }
    @RequestMapping(value = "/uploads", method = RequestMethod.POST)
    public List<String> uploadMultipartFile(@RequestParam("img") MultipartFile[] multipartFiles) throws IOException {
        List<String> imgList = new ArrayList<>();
        for (MultipartFile multipartFile : multipartFiles) {
            String imagePath = UploadUtils.saveImage(multipartFile);
            imgList.add(imagePath);
        }
        return imgList;
    }
}

上传工具类

public class UploadUtils {
    public static final String SAVE_IMG_FILE = "images";
    public static String saveImage(MultipartFile multipartFile) throws IOException {
        // 通过配置文件获取保存的路径  注意上线的时候要修改成服务器保存的绝对路径
        ResourceBundle bundle = ResourceBundle.getBundle("sys");
        //获取到了跟路径
        String rootPath = bundle.getString("root.upload.path");
        // 获取保存图片名字的统一前缀
        String imgSuffix = bundle.getString("img.suffix");
        // 生成图片保存路径 根据日期保存
        String imagePath = String.format("%s%s%s", SAVE_IMG_FILE, File.separator, DateFormatUtils.format(new Date(), "yyyyMMdd"));
        /**
         * 保存到服务器数据库的路径
         */
        String savePath = String.format("%s%s%s", imagePath, File.separator, getFileName(imgSuffix, multipartFile.getOriginalFilename()));
        // 拼接保存的路径
        //     根路劲  +  业务需求的路径 +  文件名
        File imgFile = new File(String.format("%s%s%s",rootPath,File.separator ,savePath));
        // 创建保存图片的文件
        FileUtils.touch(imgFile);
        // 将客服端图片写到文件中
        FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), imgFile);
        return savePath;
    }
    /**
     * 获取
     * @param oldName
     * @return
     */
    public static String getFileName(String suffixName, String oldName) {
        // 对图片进行重命名
        String prefix = suffixName + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
        String suffix = oldName.substring(oldName.indexOf("."));
        return prefix + suffix;
    }
}

配置文件

sys.properties

# 文件大小最大值 单位kb 50M
maxUploadSize=52428800
# 单个文件限制大小 5m
maxUploadSizePerFile=5242880
# 设置文件编码
defaultEncoding = UTF-8
# 文件上传相关路径
# 主路径  修改成你自己的
root.upload.path=/Users/xxx/xxx/upload
img.suffix = IMG_
file_suffix = FILE_

mvc配置文件

<!--注意id的值是固定的 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
    <!-- 默认编码 -->
    <property name="defaultEncoding" value="${defaultEncoding}" />
    <!-- 文件大小最大值 -->
    <property name="maxUploadSize" value="${maxUploadSize}" />
    <!--    单个文件限制大小 -->
    <property name="maxUploadSizePerFile" value="${maxUploadSizePerFile}"/>
    <!-- 内存中缓存的最大值 -->
    <property name="maxInMemorySize" value="${maxInMemorySize}" />
<!-- 为true时,启用推迟文件解析,以便在UploadAction中捕获文件大小异常-->
    <property name="resolveLazily" value="${resolveLazily}"/>
</bean>

前端

  • 为了能上传文件,必须将表单的method设置为POST或者PUT
  • 并将enctype设置为multipart/form-data
    普通表单
<h2>单文件上传</h2>
<form id='uploadForm' method="post" enctype="multipart/form-data">
    <input type="file" name="img">
    <button id='upload'>上传</button>
</form>
<h2>多文件上传</h2>
<form method="post" enctype="multipart/form-data">
    <input type="file" name="imgs" multiple>
  <button id='upload'>上传</button>
</form>

ajax

$('#upload').click(function () {
   let formData = new FormData($('#uploadForm')[0]);
    $.ajax({
        url:'http://localhost:8080/upload/',
        dataType:'json',
        type:'POST',
        data: formData,
         // 使数据不做处理
        processData : false,
        // 不要设置Content-Type请求头
        contentType : false,
        success: function(data){
            if (data.status == 'ok') {
                alert('上传成功!');
            }
        },
        error:function(response){
            console.log(response);
        }
    });
})

三、核心类介绍

MultipartFile

方法 说明
InputStream getInputStream() 获取文件流
getOriginalFilename() 获取上传文件的原名
boolean isEmpty() 判断文件是否为空
void transferTo(File dest) 保存文件到指定的文件中,注意父路径一定要存在
String getContentType() 获取文件MIME类型

CommonsMultipartResolver

属性 说明
uploadTempDir 设置上传文件时的临时目录,默认是Servlet容器的临时目录。
maxUploadSize 设置允许上传的总的最大文件大小,以字节为单位计算。当设为-1时表示无限制,默认是-1
maxUploadSizePerFile maxUploadSizePerFile是限制每个上传文件的大小
maxInMemorySize 设置在文件上传时允许写到内存中的最大值,以字节为单位计算,默认是10240
resolveLazily 为true时,启用推迟文件解析,以便在UploadAction中捕获文件大小异常。
defaultEncoding 表示用来解析request请求的默认编码格式,当没有指定的时候根据有些时候Servlet规范会使用默认值ISO-8859-1。当request自己指明了它的编码格式的时候就会忽略这里指定的

四、总结

前端

  • 请求方式一定要是post请求或者put请求
  • 请求的conentType必须是 multipart/form-data

文件

  • 对图片进行重命名,一般根据时间戳或者uuid生成规则,避免文件覆盖的现象
  • 保存的路径也根据实际的业务场景来动态生成

多文件上传

  • 使用MultipartFile[]数组来接受,使用集合来接受保存的路径
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容