【springboot项目开发】文件上传与下载

news2025/2/26 7:08:36

目录

总体介绍

文件上传

介绍

文件上传的前端需求

文件上传的前端代码

文件上传的后端需求

文件上传的后端代码

文件下载

介绍

前端需求

前端代码

后端需求

后端代码


总体介绍

文件的上传和下载功能,是项目开发过程中比较常见的业务需求,我们在客户端被展现的视觉效果通过如下:在项目前端页面的提示下将本地文件加入到浏览器的具体位置,之后浏览器直接将这个图片回显了,具体效果如下:

 但是在我们视觉效果下的上传文件并非单一的文件上传过程:而是由文件的上传和下载两部分组成,即文件从客户端本地上传到服务器和由服务器把文件在浏览器进行回显(下载到服务器中),接下来我们对两个过程进行具体介绍

文件上传

介绍

文件上传,也称为上传,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程.文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能.

文件上传的前端需求

 但是在实际的开发过程中,前端页面有关这一部分的设计通常是使用组件进行封装,例如使用element-ui在完成功能实现的基础上实现了对上传组件页面设计的优化。(底层仍然是使用post表单的方式进行发送请求)

如下:

 

文件上传的前端代码

具体实现上传功能的element-ui的代码如下:
 

 <div class="addBrand-container" id="food-add-app">
    <div class="container">
        <el-upload class="avatar-uploader"
                action="/common/upload"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :before-upload="beforeUpload"
                ref="upload">
            <img v-if="imageUrl" :src="imageUrl" class="avatar"></img>
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
    </div>
  </div>

文件上传的后端需求

服务端要接收客户端页面上传的文件,通常都会使用Apache的两个组件:

  • commons-fileupload
  • commons-io

Spring框架在spring-web包中对文件上传进行了封装,大大简化了服务端代码,我们只需要在Controller的方法中声明一个MultipartFile类型的参数即可接收上传的文件,例如:

 

关于对于文件上传的后端实现逻辑,一般是如下的实现思路:

1.首先使用MultipartFile类的形参接收客户端传来的文件,我们需要注意的是:MultipartFile类对象接收到文件之后,会对文件进行一个暂存,生成一个临时文件,当我们结束此次传输过程之后,无论是否对文件进行了转存,这个临时文件都会消失,

2.因此我们下一步的操作就是对这个暂时文件进行转存,因为文件转存过程中必然会涉及到文件名的问题,如果使用原有文件的文件名可能会存在文件名重复的问题,因此在原来的基础上生成一个新的随机文件名,以新的文件名进行转存,

2.最后一定要记得返回我们新生成的那个文件名,因为upload只是将文件上传到服务器了,后面还涉及一次将文件在浏览器上进行回显的工作,需要使用到这个文件名

我们给出文件上传的后端代码实现:

文件上传的后端代码

我们通过使用@Value注解从配置文件中读取文件保存路径:
 

 @Value("${reggie.path}")
    private String path;
reggie:
  path: D:\img\
 @PostMapping("/upload")
    public R<String>upload(MultipartFile file){
        log.info(file.toString());
        //获取原始文件名,提取JPG
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        //生成随机文件名
        String random=UUID.randomUUID().toString();
        //获取新名称
        String fileName=random+suffix;
        //创建新名称
        File file1 = new File(path);
        if(!file1.exists()){
            file1.mkdirs();
        }
        //进行转存
        try {
            log.info("文件路径为"+path+fileName);
            file.transferTo(new File(path+fileName));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return R.success(fileName);
    }

notes:关于MultipartFile类对象名:这个对象名必须与前端传来的对象名保持一致,也就是说是前后端的交互是以对象名进行匹配的,如果对象名不一致,传到后端的MultipartFile文件对象就是一个空对象了,具体演示如下:

文件下载

介绍

文件下载,也被称为download,是指将文件从服务器传到本地计算机的过程

通过浏览器进行文件下载,通常有两种表现形式:

  • 以附件形式进行下载,弹出保存对话框,将文件保存到指定的磁盘目录
  • 直接在浏览器中打开

通过浏览器进行文件下载,本质上就是服务端将文件以流的形式协会到浏览器的过程

前端需求

想要实现完整图片回显的功能,下载之前必须要完成上传功能,并且要拿到需要回显文件的文件名,所以前端的需求就是根据upload响应返回的文件名向服务端发送新的请求获取文件信息,以此进行照片信息的回显,代码实例和具体的请求url如下

代码示例:

url展示:我们可以发现,download的url中包含了具体图片的文件名

前端代码

具体的前端代码如下:

  methods: {
          handleAvatarSuccess (response, file, fileList) {
              this.imageUrl = `/common/download?name=${response.data}`
          },
          beforeUpload (file) {
            if(file){
              const suffix = file.name.split('.')[1]
              const size = file.size / 1024 / 1024 < 2
              if(['png','jpeg','jpg'].indexOf(suffix) < 0){
                this.$message.error('上传图片只支持 png、jpeg、jpg 格式!')
                this.$refs.upload.clearFiles()
                return false
              }
              if(!size){
                this.$message.error('上传文件大小不能超过 2MB!')
                return false
              }
              return file
            }
          }
        }

后端需求

后端接收到前端传来的文件名,根据文件路径和文件名创建FileInputStream对象,利用response对象创建ServletOutputStream对象,从FileInputStream文件中读取数据并通过数组写入ServletOutputStream对象,最后记得一定要关闭流资源

后端代码

 后端代码如下:

 

 @GetMapping("/download")
    public void downLoad(String name, HttpServletResponse response){
        //输入流,通过提供指定位置去读取数据
        try {
            FileInputStream fileInputStream = new FileInputStream(new File(path + name));
            //输出流,通过读取到的数据输出到浏览器中
            ServletOutputStream outputStream = response.getOutputStream();
            response.setContentType("image/jpeg");
            //将数据通过byte字符数组进行读取
            int len=0;
            byte[]bytes=new byte[1024];
            while((len=fileInputStream.read(bytes))!=-1){
                outputStream.write(bytes,0,len);
                //刷新
                outputStream.flush();
            }
            fileInputStream.close();
            outputStream.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开源 Golang 微服务入门二:RPC 框架 Kitex

前言 前一篇笔记介绍了字节跳动的开源 Golang 微服务 HTTP 框架 Hertz&#xff0c; 如下&#xff1a; 开源 Golang 微服务入门一&#xff1a; HTTP 框架 Hertz 本文将要介绍同样是字节跳动开源的 Golang 微服务 RPC 框架 Kitex。 Kitex 简介 Kitex 字节跳动内部的 Golang 微…

nacos高级

一、什么是配置中心 在微服务架构中&#xff0c;当系统从一个单体应用被拆分成分布式系统上的一个个服务节点后&#xff0c;配置文件也必须跟着迁移&#xff08;分割&#xff09;&#xff0c;这样配置就分散了。不仅配置会分散&#xff0c;分散中还会包含着冗余。 配置中心将…

Linux进程、用户、权限命令

进程管理命令 进程和程序的区别 1 程序是静态概念&#xff0c;本身作为一种软件资源长期保存&#xff1b;而进程是程序的执行过程&#xff0c;它是动态概念&#xff0c;有一定的生命期&#xff0c;是动态产生和消亡的。 2 程序和进程无一一对应关系。一个进程在活动中可有顺序…

顺序表和链表的比较

本文主要内容&#xff1a;从存取方式、逻辑/物理结构、查找/插入/删除操作和空间分配的角度比较顺序表和链表&#xff0c;并从存储、运算、环境的角度对比应如何选取存储结构。 目录 一、顺序表和链表的比较1、存取&#xff08;读写&#xff09;方式2、逻辑/物理结构3、查找、…

AI人工智能领域精美绘图模板分享

1 人工智能的发展历程 如今人工智能的应用渗透了我们生活的方方面面&#xff0c;我们都知道人工智能的前景十分光明&#xff0c;在未来对于推进人类发展进程也是非常重要的&#xff0c;但其实人工智能的发展道路是极其曲折的&#xff0c;下面就将人工智能的发展历程分为如下六…

arcgis for javascript TileLayer 自定义高德地图图层

效果如图&#xff1a; 一、创建自定义切片层 要创建自定义图块层&#xff0c;您必须调用BaseTileLayer类的createSubclass()方法。命名自定义层为TintLayer 由于这一层需要知道在哪里访问预定义的图块&#xff0c;我们将创建一个属性。应用程序将为图层提供值&#xff0c;图…

全球首发 《NGINX 完全指南》中文版

原文作者&#xff1a;Derek DeJonghe of F5 原文链接&#xff1a;全球首发 | 《NGINX 完全指南》中文版 转载来源&#xff1a;NGINX 开源社区 NGINX唯一中文官方社区 &#xff0c;尽在nginx.org.cn 在社区小伙伴们的催促下&#xff0c;我们很高兴地与大家分享这个好消息&#…

关于阵列发射端的波束形成(相控阵)研究与仿真实践

说明 相控阵是一个很大的话题&#xff0c;相控阵说得直白一点就是通过控制天线阵列中各个天线的相位来使得波束指向我们想要的方向。现阶段相控阵雷达用得更多的还是军事领域&#xff0c;不过随着技术的进步、成本的下降以及小型化&#xff0c;相控阵雷达也逐渐被用于民用领域了…

Python之Gradio简单使用

目录 安装Gradio示例用法应用界面1. gr.Interface2. gr.Blocks Gradio的输入和输出组件输入组件&#xff08;Inputs&#xff09;输出组件&#xff08;Outputs&#xff09; 其他 Gradio是一个Python库&#xff0c;用于构建快速的Web界面&#xff0c;以便于使用机器学习模型进行实…

Vue.js 中的 watch 属性详解

Vue.js 中的 watch 属性详解 在 Vue.js 中&#xff0c;watch 属性是一种非常重要的属性&#xff0c;它可以监听 Vue 实例中指定的数据变化&#xff0c;并在数据发生变化时执行相应的操作。本文将对 Vue.js 中的 watch 属性进行详细的介绍&#xff0c;并附上相关的代码示例。 什…

一文看穿 TypeScript 的庐山真面目

导语&#xff1a; 在了解 TypeScript 之前&#xff0c;我们需要了解 什么是强类型语言和什么是弱类型语言&#xff0c;以及什么是静态类型&#xff0c;什么又是动态类型。 强类型不允许任意的隐式类型转换&#xff0c;而 弱类型 允许静态类型&#xff1a;一个变量声明时它的类型…

基于Python的大数据舆情分析,舆论情感分析可视化系统

运行效果图 基于Python的微博大数据舆情分析&#xff0c;舆论情感分析可视化系统 系统介绍 微博舆情分析系统&#xff0c;项目后端分爬虫模块、数据分析模块、数据存储模块、业务逻辑模块组成。 先后进行了数据获取和筛选存储&#xff0c;对存储后的数据库数据进行提取分析处…

sqlmap -os-shell 使用方法

一、burp suite抓包。 如上图所示&#xff0c;红框处很明显是一个传参点&#xff0c;我们就在这个页面抓包。 抓到包之后将内容保存到桌面的1000.txt文件下。 二、sqlmap跑包。 打开sqlmap跑包。 python sqlmap.py -r C:\Users\16434\Desktop\1000.txt -dbmsmysql --os-shell…

Oracle-catalog影响归档量统计

有个12.2 rac环境报警备份异常&#xff0c;登录检查备份&#xff0c;发现报错日志 piece handle/backup/orcl/archbackup/ARCHBAK_ORCL_20230607_738_1 tagARCH_BAK commentNONE channel d1: backup set complete, elapsed time: 00:01:55 released channel: d1 RMAN-00571: …

从Vuex过渡到pinia

Vuex过渡到Pinia 众所周知&#xff0c;Vuex是一个状态管理库&#xff0c;它方便了我们任何组件不用考虑关系就可以共享一个全局的状态。&#x1f603;但是 Vuex也有它一定的缺陷。主要缺点&#xff0c;我总结如下&#xff1a; mutations里面不能写异步函数&#xff0c;否则就…

Simulink仿真模块 - Waveform Generator

Waveform Generator模块的功能是使用信号符号输出波形。它所在的库为: Simulink / Sources 如图所示: 双击模型弹出如下对话框,如图所示: Waveform Generator 模块根据您在波形定义表中输入的信号符号输出波形。 此模块支持下列用于信号符号的语法: 函数…

STM32单片机OLED语音识别路灯台灯控制系统人检测亮度调节

实践制作DIY- GC0143-OLED语音识别路灯台灯控制系统 基于STM32单片机设计---OLED语音识别路灯台灯控制系统 二、功能介绍&#xff1a; 电路&#xff1a;STM32F103C系列最小系统串口语音识别模块LED灯板1个红外传感器OLED显示器1个手动自动模式键1个开关按键 1.有两个模式1个手…

速卖通,国际站,temu测评,补单策略:安全与效能并重,提高账号存活率

测评能够帮助卖家让亚马逊平台更喜欢自己的产品&#xff0c;给予更好排名的同时也让后续进入店铺的买家更容易认可自己的产品。这些真实评价在亚马逊卖家管理系统中被称为Review Feedback。这是进行真实交易后形成的评价&#xff0c;而不是通过机器软件生成&#xff0c;形成虚拟…

SpringData进阶篇-下

SpringData进阶篇 一&#xff1a;故事背景二&#xff1a;自定义操作2.1 JPQL和SQL2.1.1 接口内定义2.1.2 调用2.2.3 SQL 方式查询 2.2 规定方法名2.2.1 普通查询规则2.2.2 修饰查询 2.3 Query By Example2.3.1 Repository继承QueryByExampleExecutor2.3.2 具体使用2.3.2 Exampl…

Aspose.Words功能演示:使用 C# 从 Word 文档中读取宏

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c; Aspose API支持流行文件格式处…