Spring 中MultipartFile 工具类的方法介绍

437 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情

什么是MultipartFile

MultipartFile 工具类是Spring MVC 框架为了方便开发,提供的一个简化文件上传操作的工具类。

其实在不使用Spring MVC 框架之前,我们在开发的时候,都是使用原生的Servlet 中的HttpServletRequest 来传递上传的数据。用户将文件数据赋给HttpServletRequest 类,然后这些文件就以二进制流的方式传递到后端。后端收到数据之后,需要我们自己考虑如何将这些数据转换为File 类,然后才能使用。

上面的步骤看起来就很麻烦,我们不仅需要清除文件上传的时的机制,还要了解servlet 的相关知识等等。由于上面所说的方式比较繁琐,于是出现了很多工具类,MultipartFile 工具类就是其中一种。在相关的文件上传工具类出现之后,我们再操作上传文件的时候就简单得多了。

什么是流

在开始介绍MultipartFile 之前,我们首先要认识一下Java 中的流,要知道流是什么:

  1. 流本身是一个抽象概念,它将输入输出设备做了一种抽象化的归纳。在java 中,我们对数据的输入输出操作都是通过“流”的方式来完成的。
  2. 流的分类包括:输入流和输出流,但是它们是相对的,根据名字我们可以看得出来,流是具有方向的。
  3. 在客户端程序需要从数据源中读入数据的时候,系统就会开启一个输入流;相反,当客户端想要写出数据到某个目的地的时候,就会开启一个输出流。(数据源可以是文件、内存或者网络)

MultipartFile 工具类方法介绍

接下来我们来看一下MultipartFile 工具类的各个方法。

我们参照着代码来看:

package org.springframework.web.multipart;

// 省略import

public interface MultipartFile extends InputStreamSource {

getName() 方法的作用是返回参数的名称

    String getName();

这个方法用来获取源文件的昵称

    @Nullable
    String getOriginalFilename();
//getContentType() 返回文件的内容类型
    @Nullable
    String getContentType();

通过isEmpty() 方法判断是否为空,以及判断上传的文件是否有内容

    boolean isEmpty();

getSize() 方法返回文件大小,单位是字节

    long getSize();

getBytes() 将文件内容转化成一个byte 数组,然后返回

    byte[] getBytes() throws IOException;

getInputStream() 返回InputStream读取文件的内容

    InputStream getInputStream() throws IOException;
    default Resource getResource() {
        return new MultipartFileResource(this);
    }

transferTo(File dest) 用来把 MultipartFile 转换换成 File

    void transferTo(File var1) throws IOException, IllegalStateException;

    default void transferTo(Path dest) throws IOException, IllegalStateException {
        FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
    }
}

我们可以看到,MultipartFile 继承了InputStreamSource 接口,对于InputStreamSource 这个接口,它本质上返回的还是一个InputStream 流对象。

package org.springframework.core.io;

import java.io.IOException;
import java.io.InputStream;

public interface InputStreamSource {
    // 这个方法用来定位并打开资源,返回资源对应的输入流。当然,在调用者在使用完毕后必须关闭该资源。 
    InputStream getInputStream() throws IOException;
}

在我们实际开发中,文件上传功能我们可以写一些util 类来完成对于的工作,但是如果前端可以做一些前置校验,会省去很多服务端的压力,同时也减少很多耗时。比如说文件命名、文件大小、文件格式等等。

当然,在后端Java 代码中也必须要写一些校验相关的代码,来帮助我们筛选过滤上传的文件,示例代码如下:

    private String validateUploadedImageAndGetFileName(MultipartFile file) {
        if (file == null) {
            // 抛异常或者直接返回,根据业务需求定制
            return "";
        }
        if (file.getSize() > 20 * 1024 * 1024) {
            throw new RuntimeException("图片大小超出限制");
        }
        boolean isPicture = FileUtil.isPicture(file.getOriginalFilename());
        if (!isPicture) {
            throw new RuntimeException("图片格式错误");
        }
        String fileName = Objects.requireNonNull(file.getOriginalFilename()).length() > 50 ? file.getOriginalFilename().substring(0, 50) : file.getOriginalFilename();
        return fileName;
    }

总结

至此介绍完成