Spring Boot 文件上传

Spring Boot 文件上传

原文链接:https://www.javaboy.org/2021/0415/servlet3.0-fileupload.html

码云地址:https://gitee.com/li-jie-jie/springboot0-study/tree/master

本地项目地址:D:\javalab\MyIDEAJavaSpring-Boot\spring-study\fileupload

1.两种文件解析方案

对于上传文件的请求,SpringMVC 中目前共有两种不同的解析方案:

  • StandardServletMultipartResolver 支持 Servlet3.0 中标准的文件上传方案,使用非常简单。可以直接通过 HttpServletRequest 自带的 getPart 方法获取上传文件并保存,这是一种标准的操作方式,这种方式也不用添加任何额外的依赖,只需要确保 Servlet 的版本在 3.0 之上即可。

  • CommonsMultipartResolver 则需要结合 Apache Commons fileupload 组件一起使用,这种方式兼容低版本的 Servlet。

本文讲的是:StandardServletMultipartResolver。

2.后端代码:

注意事项:

  1. 保存的文件不能重名,这里使用UUID.randomUUID()来保证不重名
  2. 一个文件夹如果保存太多资源,会导致文件夹打开太慢,这里使用日期来分类。

2.1 controller层

@RestController
@RequestMapping("/file")
public class FileUploadController {
    /**
     * 通过时间创建不同的文件夹,当天下载的文件放在当天的文件夹下,注意后面的“/”不能少,
     */
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd/");

    @PostMapping("/load")
    public String fileUpload(MultipartFile file, HttpServletRequest request) {
        String format = simpleDateFormat.format(new Date());
        //获取服务器存储的真实路径
        String realPath = request.getServletContext().getRealPath("/img") + format;
        //如果文件夹不存在就创建
        File folder = new File(realPath);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        //获取上传的文件名
        String oldName = file.getOriginalFilename();
        //用随机产生的UID+源文件名的后缀,作为新的文件名
        String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
        try {
            //transferTo,中文转移,也就是把file转移到新的文件中。其实就是拷贝
            file.transferTo(new File(folder, newName));
            //返回请求地址url,通过这个地址就可以访问到上传的文件
            String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/img"
                    + format + newName;
            return url;
        } catch (IOException e) {
            e.printStackTrace();
        }
        //上传失败就返回"error"
        return "error";
    }
}

使用这种方式我们什么都不用配了,spring boot已经帮我们配置好了。但是我们想要配置限制文件大小等,要怎么配置呢?我们可以在yml配置文件中进行配置。

2.2 yml配置

spring:
  servlet:
    multipart:
      max-file-size: 1MB  #上传单个文件最大容量,注意MB单位是大写的
      max-request-size: 10MB #最大请求容量
      enabled: true #是否启用StandardServletMultipartResolver
      location:      #上传文件的临时目录,如果上传的文件很大的话,就需要一个临时目录.
      resolve-lazily: false #是否支持 multipart 上传文件时懒加载
      file-size-threshold: 0 #支持文件写入磁盘

3. 前端页面

前端这里有两种方式上传文件:

  1. from表单
  2. jquery的ajax

3.1from表单上传文件

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

</form>
</body>
</html>

3.2 Ajax上传文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<!--    注意script不能自结束-->
    <script src="jquery-3.6.0.js"></script>
</head>
<body>

<div id="result"></div>
<input type="file" id="file">
<input type="button" value="上传" onclick="uploadFile()">


<script>
    function uploadFile() {
        // $('#file')是juery对象,加上[0]变为javaScript对象,然后获取到文件
        var file = $('#file')[0].files[0]
        //将文件添加到FormData
        var formData = new FormData()
        formData.append("file", file);
        $.ajax({
            type: 'post',
            url: '/file/load',
            processData: false,//把上传的数据转换成Java对象,默认为true
            contentType: false,//设置请求头,要避免设置请求头,可能会破环里面的分隔符
            data: formData,
            success: function (msg) {
                $("#result").html(msg);
            }
        })
    }
</script>
</body>
</html>

这里我犯了一个错误script自结束,导致整个页面加载不出来。

 <script src="jquery-3.6.0.js"/>

另外将jquery导入但是访问不到,这可能是target包中没有生成。把它删了重新启动项目即可。

4. 多文件上传

只要明白了单文件上传,多文件上传就很简单,

4.1controller层:

MultipartFile[]改为数组,然后遍历flie进行上传。

  /**
     * 多文件上传
     */
    @PostMapping("/multipleLoad")
    public void multipleFileUpload(MultipartFile[] files, HttpServletRequest request) {
        String format = simpleDateFormat.format(new Date());
        //获取服务器存储的真实路径
        String realPath = request.getServletContext().getRealPath("/img") + format;
        //如果文件夹不存在就创建
        File folder = new File(realPath);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        for (MultipartFile file : files) {
            //获取上传的文件名
            String oldName = file.getOriginalFilename();
            //用随机产生的UID+源文件名的后缀,作为新的文件名
            String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
            try {
                //transferTo,中文转移,也就是把file转移到新的文件中。其实就是拷贝
                file.transferTo(new File(folder, newName));
                //返回请求地址url,通过这个地址就可以访问到上传的文件
                String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() +
                        "/img"
                        + format + newName;
                System.out.println(url);
            } catch (IOException e) {
                e.printStackTrace();

            }
        }
    }

4.2前端页面

<form action="/file/multipleLoad" enctype="multipart/form-data" method="post">
    <input type="file" name="files" multiple>
    <input type="submit" value="提交">

</form>

注意input标签要加上multiple属性表示可以选择多个文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值