Spring Boot (十九)——实现文件上传

文件上传是项目开发中最常见的功能,springboot同样支持文件上传,需要使用到MultipartFile,MultipartFile是spring类型,代表HTML中form data方式上传的文件,包含二进制数据+文件名称。
下面具体实现以下文件上传的几种场景:

单文件上传

在springboot中我们实现文件上传,不需要我们添加额外的依赖,已经有默认的配置,我们只需要编写我们的上传逻辑即可,controller如下:

@RestController  //这里用RestController的意思是我们不想返回一个页面,返回的是我们文件上传的路径
public class FileUploadController {
    SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/"); //这里使用SimpleDataFormat的意思是我们文件上传建议对文件分类,这里就使用日期分类
    @PostMapping("/upload") //注意,文件上传必须是post请求
    public String upload(MultipartFile file, HttpServletRequest req){//HttpServletRequest用了获取文件保存地址,这里简单处理,将文件保存在项目运行的路径下
        String format = sdf.format(new Date());
        String realPath = req.getServletContext().getRealPath("/img")+ format; //图片最终保存的位置
        File folder = new File(realPath);//创建一个文件夹
        if (!folder.exists()){ //如果文件夹不存在,就创建一个
            folder.mkdirs();
        }
        //给上传的文件起一个不会重名的名字
        String oldName = file.getOriginalFilename();//获取文件的原名
        String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));//新文件名为UUID+文件后缀
        //保存文件
        try {
            file.transferTo(new File(folder, newName));
            //如果保存失败,我们返回文件的路径
            //这里需要注意的是,我们不清楚请求是http还是https,所以不能写死,要动态地获取,其中:
            //req.getScheme:返回当前链接使用的协议;比如,一般应用返回http;SSL返回https
            //req.getServerName:返回请求网站的域名
            //req.getSercerPort:返回请求网站的端口
            String url = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/img" + format + newName;
            return url;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "error";//如果保存失败,返回提示
    }
}

在resource/statics目录下创建一个index.html页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <!--注意:name="file"需要和后台参数名称对应-->
    <input type="file" name="file">
    <input type="submit" value="提交">
</form>
</body>
</html>

访问页面,上传一张图片:
在这里插入图片描述
上传成功,返回文件存放路径:
在这里插入图片描述

我们直接访问这个路径,可以看到图片直接访问到了:

那么,Springboot中有没有文件上传的一些配置呢?比如比如上传文件的大小限制等,那肯定是有的,Springboot中一直贯穿的一个思想就是,你没配置就用默认的,配置了就用配置的,实际上是有默认配置的,我们如果想要修改,直接在application.properties中配置,只需要搜索multipart就出来了,比如这里我们设置单个文件上传的大小为1KB:

#上传的单个文件的大小
spring.servlet.multipart.max-file-size=1KB
#上传的文件总大小
spring.servlet.multipart.max-request-size=10MB

重启项目,上传文件会报错:
在这里插入图片描述
报错也很明显,超过为文件大小限制。

Ajax实现文件上传

在Springboot中同样可以使用ajax实现文件的上传,后端代码基本不变,前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="jquery-3.3.1.js"></script>
</head>
<body>
<div id="result"></div>
<input type="file" id="file">
<input type="button" value="提交" onclick="fileupload()">
<script>
    function fileupload(){
        var file = $("#file")[0].files[0]; //这里是单文件上传去数组中的第一个
        var formData = new FormData(); //FormData对象可以让我们组织一个使用XMLHttpRequest对象发送的键值对的集合。
                                      // 它主要用于发送表单数据,但是可以独立于使用表单传输的数据。
        formData.append("file", file);
        $.ajax({
            type:'post',
            url:'/upload',
            processData:false, //意为要不要把我们上传的数据处理为一个对象,默认为true,我们设置为false
            contentType:false,//避免让jQuery设置请求头
            data:formData,
            success:function (msg) {
                $("#result").html(msg);
            }
        })
    }
</script>
</body>
</html>

请求效果如下:
在这里插入图片描述
图片上传成功,访问图片路径依然是成功的。

注意
1、IDEA中导入js文件直接将文件拖入页面中,不用写代码导入,非常方便。
2、注意细节,错误地将Ajax中的“ processData”属性拼写成了“ processDate”,一个单词写错导致ajax请求失败,查找原因费了不少时间,罪过啊!

多文件上传

如果是多文件上传,前后台都需要修改一下:
前台:

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

多文件上传的话,input框要加上“multiple”,后台用一个数组接受,所以name值改为files。

后台代码修改如下:

@PostMapping("/uploads")
    public String uploads(MultipartFile[] files, HttpServletRequest req){
        String format = sdf.format(new Date());
        String realPath = req.getServletContext().getRealPath("/img")+ format;
        File folder = new File(realPath);
        if (!folder.exists()){
            folder.mkdirs();
        }
        for (MultipartFile file : files) { //使用数组接受,这里遍历一下就可以了,其他不用修改
            String oldName = file.getOriginalFilename();
            String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
            try {
                file.transferTo(new File(folder, newName));
                String url = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/img" + format + newName;
                System.out.println(url);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "success";
    }

访问页面,选择两个文件,点击上传:
在这里插入图片描述
在这里插入图片描述
控制台打印的路径也能正常访问的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值