Spring Web文件上传功能简述

文章目录

  • 正文
    • 简单文件上传
    • 文件写入
  • 总结

正文

在日常项目开发过程中,文件上传是一个非常常见的功能,当然正规项目都有专门的文件服务器保存上传的文件,实际只需要保存文件路径链接到数据库中即可,但在小型项目中可能没有专门的文件服务器用来存储这些文件,这时就需要我们自己手动实现文件上传功能了。

简单文件上传

在SpringWeb项目中要想实现文件上传也很简单,通过接收 MultipartFile类型的文件即可接收到文件参数,一个简单的文件上传Controller接口代码如下

@RestController
@RequestMapping("/test")
public class TestController {
    @CrossOrigin
    @PostMapping("/file")
    public String testFileUpload(MultipartFile file){
        String oriName = file.getOriginalFilename();
        return "已收到上传文件:"+oriName;
    }
}

这时只需要前端通过<input type="file"/>标签获取文件并使用FormData的方式上传即可,简单代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FileUploadDoc</title>
    <style>
        .contain{
            margin-left: 300px;
            margin-top: 100px;
            border: blanchedalmond solid;
            width: 310px;
            padding: 10px;
        }
    </style>
</head>
<body>
<div class="contain">
    <input id="uploadedInput" type="file" name="uploadedFile">
    <button id="submitBtn">提交</button>
</div>
</body>
<script>
    let btn = document.getElementById("submitBtn")
    let fileInput = document.getElementById("uploadedInput")
    btn.addEventListener("click",()=>{
        let fileData=fileInput.files[0]
        let formData = new FormData()
        formData.append("file",fileData)
        //注意:这里不需要设置Content-Type参数
        let xhr = new XMLHttpRequest();
        xhr.open("POST","http://localhost:18080/test/file")
        xhr.send(formData)
        xhr.onreadystatechange=()=>{
            if (xhr.status===200){
                console.log(xhr.responseText)
            }
        }
    })
</script>
</html>

效果如下

在这里插入图片描述

选择文件后,通过点击提交按钮即可将所选文件上传到后端服务器。

这里有一个问题需要注意,如果上传失败报错,需要设置

  1. 最大文件大小,参数名spring.servlet.multipart.max-file-size,默认值1MB

  2. 单个请求最大值 ,参数名spring.servlet.multipart.max-request-size,默认值10MB

这两个参数,在SpringBoot项目中由于存在默认配置,可以不设置,若需要修改默认值则需根据实际情况设置这两个参数。

如果超出尺寸大小的限制会抛出这两个异常

  1. 文件大小超出限制异常为 FileSizeLimitExceededException
  2. 请求内容超出限制异常为 SizeLimitExceededException

文件写入

一般情况下的上传业务,需要将文件写入到固定的文件夹下,而当遇到同名文件时需要覆盖原来的文件。面对这种业务逻辑需要修改代码如下

@CrossOrigin
@PostMapping("/file")
public String testFileUpload(MultipartFile file) throws IOException {
    if (file == null) {
        return "上传文件不能为空";
    }

    //获取文件名
    String oriName = file.getOriginalFilename();
    //文件保存文件夹
    String dirPath = "D:\\Activities\\temp_files";
    File serverFile = new File(dirPath, oriName);
    //判断文件是否存在
    if (serverFile.exists()) {
        serverFile.delete();
    } else {
        serverFile.createNewFile();
    }
    //读取文件并上传
    try (InputStream input = file.getInputStream();
         BufferedInputStream bIn = new BufferedInputStream(input);
         OutputStream output = new FileOutputStream(serverFile);
         BufferedOutputStream bOut = new BufferedOutputStream(output)) {
        byte[] byteArr = new byte[1024];
        int len = 0;
        while ((len = bIn.read(byteArr)) > 0) {
            bOut.write(byteArr, 0, len);
        }
    }

    return "已收到上传文件:" + oriName;
}

另一种常见的业务逻辑是,校验文件格式(如:只支持txt文件格式)后,对其进行重命名后返回一个网络地址,这时可使用以下代码

@CrossOrigin
@PostMapping("/file")
public String testFileUpload(MultipartFile file) throws IOException {
    if (file == null) {
        return "上传文件不能为空";
    }

    StringBuffer fileNameBuf = new StringBuffer();
    fileNameBuf.append(System.currentTimeMillis()).append(UUID.randomUUID());
    String oriName = file.getOriginalFilename();
    //校验.txt和.TXT文件格式
    Pattern pattern = Pattern.compile("^.+[.txt|.TXT]$");
    if(pattern.matcher(oriName).matches()) {
        fileNameBuf.append(".txt");
    }else{
        return "文件格式错误,只支持txt文件";
    }

    String dirPath = "D:\\Activities\\temp_files";
    File serverFile = new File(dirPath, fileNameBuf.toString());
    if (serverFile.exists()) {
        return "文件上传失败,请重试";
    } else {
        serverFile.createNewFile();
    }
    try (InputStream input = file.getInputStream();
         BufferedInputStream bIn = new BufferedInputStream(input);
         OutputStream output = new FileOutputStream(serverFile);
         BufferedOutputStream bOut = new BufferedOutputStream(output)) {
        byte[] byteArr = new byte[1024];
        int len = 0;
        while ((len = bIn.read(byteArr)) > 0) {
            bOut.write(byteArr, 0, len);
        }
    }

    //生成网络链接
    StringBuffer webPath = new StringBuffer("文件上传成功,文件访问链接为:");
    webPath.append("https://img.sunyog.top/temp_files/").append(fileNameBuf);
    return webPath.toString();
}

总结

本文简单介绍了在Spring Web项目中文件上传相关的业务,在Spring中文件上传通过接收 MultipartFile类型的参数即可实现,获取到文件后可根据具体的业务逻辑进行相应处理。而在JavaScript中需要做的仅仅是获取所选文件,并通过FormData传输数据即可。


📩 联系方式
邮箱: qijilaoli@foxmail.com
掘金: https://juejin.cn/user/873463590162108
CSDN: https://blog.csdn.net/qq_43408971

❗版权声明
本文为原创文章,版权归作者所有。未经许可,禁止转载。更多内容请访问我的个人中心

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/333898.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信这个费用,终于降低了

大家好&#xff0c;我是小悟 这个费用降低了&#xff0c;这对于广大小程序开发者来说无疑是一个好消息。这一举措不仅可以降低开发者的成本&#xff0c;还有助于激发更多的创新和创业激情。 对于广大小程序开发者来说&#xff0c;这也是一个福音&#xff0c;因为他们可以降低开…

Pypputeer自动化

Pyppeteer简介 pyppeteer 是 Python 语言的一个库&#xff0c;它是对 Puppeteer 的一个非官方端口&#xff0c;Puppeteer 是一个 Node 库&#xff0c;Puppeteer是Google基于Node.js开发的一个工具&#xff0c;它提供了一种高层次的 API 来通过 DevTools 协议控制 Chrome 或 Ch…

#Pytorch 使用DDP训练第一轮,验证后第二轮卡住

问题&#xff1a;在使用DDP分布式训练的时候&#xff0c;在第一轮训练后验证结果&#xff0c;在第二轮开始时就卡住了。因为设置了dist.barrier()&#xff0c;所以只有第一个GPU跑了验证&#xff0c;在第二轮时只有第一个GPU的模型在&#xff0c;其他卡的模型都被阻塞住了。 解…

Linux下使用Docker部署MinIO实现远程上传

&#x1f4d1;前言 本文主要是Linux下通过Docker部署MinIO存储服务实现远程上传的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#…

在vue中使用echarts渲染地图,geo点击某个区域可高亮,取消

一、安装echarts npm install echarts --save二、main.js引入注册 import Vue from "vue";import * as echarts from "echarts";Vue.prototype.$echarts echarts;三、vue文件中使用echarts <template><div class"page-warp"><…

mysql原理--锁

1.解决并发事务带来问题的两种基本方式 上一章唠叨了事务并发执行时可能带来的各种问题&#xff0c;并发事务访问相同记录的情况大致可以划分为3种&#xff1a; (1). 读-读 情况&#xff1a;即并发事务相继读取相同的记录。 读取操作本身不会对记录有一毛钱影响&#xff0c;并不…

聚铭入选“2023中国数字安全能力图谱(精选版)”安全运营领域

近日&#xff0c;国内权威数字安全领域第三方调研机构数世咨询正式发布《2023年度中国数字安全能力图谱&#xff08;精选版&#xff09;》。聚铭网络作为国内领先的安全运营商&#xff0c;凭借在细分领域突出优势&#xff0c;成功入选该图谱“安全运营”领域代表厂商。 据悉&a…

6.4.2转换文件

6.4.2转换文件 利用Swf2VideoConverter2可以很方便地将Flash动画(*.swf)转换为其它的视频格式。 1&#xff0e;单击“添加”按钮&#xff0c;在弹出的下拉菜单中选择“添加文件”&#xff0c;在弹出的“Open Swf Files(打开Swf文件)”窗口中选择swf文件(如&#xff1a;那些花…

使用nginx搭建网页

一、实验要求 网站需求&#xff1a; 1.基于域名www.openlab.com可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于www.openlab.com/student 网站访问学生信息&#xff0c;www.openlab.com…

element中Table表格控件单选、多选功能进一步优化

目录 一、代码实现1、 父组件2、子组件&#xff08;弹框&#xff09; 二、效果图 一、代码实现 1、 父组件 <template><div><!-- 用户选择嵌套弹框 --><el-dialog :close-on-click-modal"false" :close-on-press-escape"false" tit…

OPC UA 开源库编译方法及通过OPC UA连接西门S7-1200 PLC通信并进行数据交换

前言 在现代工业自动化领域&#xff0c;OPC UA&#xff08;开放性生产控制和统一架构&#xff09;是一种广泛应用的通信协议。本文将以通俗易懂的方式解释OPC UA的含义和作用&#xff0c;帮助读者更好地理解这一概念。 一、OPC UA的定义 OPC UA全称为“开放性生产控制和统一…

bgp--大AS分小AS

最后效果:r1能ping通r8,r4路由表有r1-r8环回,r4bgp路由表已优化 代码; [r1] ospf 1 router-id 1.1.1.1 area 0.0.0.0 network 1.1.1.1 0.0.0.0 network 12.1.1.1 0.0.0.0 bgp 64512 router-id 1.1.1.1 confederation id …

湖(岛屿)

from book&#xff1a;挑战程序设计竞赛

亿尚网:时尚电商告别红利时代回归常态未来将何去何从?

随着互联网技术的不断发展和普及&#xff0c;时尚电商行业在过去的十年里迅猛的增长&#xff0c;经历了前所未有的繁荣。然而近年来这个行业似乎已经迎来了一个转折点。曾经的高速增长和巨大利润已经逐渐消失&#xff0c;取而代之的是日益激烈的竞争和微薄的利润空间。这一切的…

TPU编程竞赛系列|第八届集创赛“算能杯“报名开启!

近日&#xff0c;第八届全国大学生集成电路创新创业大赛正式开幕&#xff0c;"算能杯"以 基于TPU处理器的边缘计算系统设计 为赛题&#xff0c;围绕算能提供的多款TPU硬件&#xff0c;展开软硬件协同设计&#xff0c;创新开发算法及探索新兴应用。我们诚邀全国高校的…

三极管这个功能比“放大”还常用?

同学们大家好&#xff0c;今天我们继续学习杨欣的《电子设计从零开始》&#xff0c;这本书从基本原理出发&#xff0c;知识点遍及无线电通讯、仪器设计、三极管电路、集成电路、传感器、数字电路基础、单片机及应用实例&#xff0c;可以说是全面系统地介绍了电子设计所需的知识…

杜卡迪Panigale v4 SP2、Street Fighter v4 SP正式发布,购车送GP观赛

最新款杜卡迪的Panigale v4 SP2、Street Fighter v4 SP国内正式上市&#xff0c;售价分别是382500元和310500元&#xff0c;Panigale售价比老款降低了2.55万元&#xff0c;而街霸的SP版则是国内首次上市。 SP版一直都是杜卡迪的限量款&#xff0c;标榜着高性能、高配置&#xf…

运放【之噪声】

电流噪声和电压噪声 我们一般评估噪声&#xff0c;还看对输出端噪声电压的贡献&#xff0c;因为电流乘以电阻等于电压&#xff0c;因此&#xff0c;最终的噪声大小还跟电路中电阻的取值有很大关系。显然&#xff0c;电阻越大&#xff0c;那么噪声电压就越大。反之电阻越小&…

HarmonyOS4.0系列——07、自定义组件的生命周期、路由以及路由传参

自定义组件的生命周期 允许在生命周期函数中使用 Promise 和异步回调函数&#xff0c;比如网络资源获取&#xff0c;定时器设置等&#xff1b; 页面生命周期 即被Entry 装饰的组件生命周期&#xff0c;提供以下生命周期接口&#xff1a; onPageShow 页面加载时触发&#xff…

烟火检测AI边缘计算智能分析网关V4如何通过ssh进行服务器远程运维

智能分析网关V4是一款高性能、低功耗的AI边缘计算硬件设备&#xff0c;它采用了BM1684芯片&#xff0c;集成高性能8核ARM A53&#xff0c;主频高达2.3GHz&#xff0c;并且INT8峰值算力高达17.6Tops&#xff0c;FB32高精度算力达到2.2T&#xff0c;每个摄像头可同时配置3种算法&…