基于SpringWeb MultipartFile文件上传、下载功能

在Web开发中,文件上传是一个常见的功能需求。Spring框架提供了MultipartFile接口,用于处理文件上传请求。MultipartFile可以代表一个多部分文件上传请求中的一个文件,提供了一系列方法用于获取文件的各种属性和内容,使得在后端处理文件上传变得十分方便。下面我们将介绍MultipartFile在Web应用中的几种常见使用场景。

1. 图片上传

在Web应用中,图片上传是一种常见的场景。用户需要上传头像、相片、证件照等图片文件,而后端需要接收并保存这些文件。使用MultipartFile接口可以轻松地实现图片文件的接收和处理。通过获取文件的原始文件名、内容类型、大小等属性,我们可以实现对图片文件的有效管理和存储。例如,我们可以将图片文件保存到服务器的文件系统中,或者将其存储到云存储服务中。

2. 文件下载

除了文件上传,文件下载也是Web应用中常见的功能需求。使用MultipartFile接口,我们可以实现文件的下载功能。在服务器端,我们可以将文件作为MultipartFile对象进行处理,并通过设置响应头信息,将文件作为下载内容返回给客户端。客户端接收到文件后,可以将其保存到本地磁盘或进行其他处理。

3. 文件编辑

在Web应用中,有时候用户需要对上传的文件进行编辑操作,例如修改文件名、修改文件内容等。使用MultipartFile接口,我们可以实现对文件的编辑功能。首先,我们可以通过MultipartFile接口获取上传的文件对象,然后对其进行相应的编辑操作。例如,我们可以修改文件的名称、修改文件的内容等。编辑完成后,我们可以将修改后的文件保存到服务器或返回给客户端。

4. 文件预览和展示

在Web应用中,有时候我们需要将上传的文件进行预览或展示。例如,在文档管理系统中,用户需要预览或下载文档文件。使用MultipartFile接口,我们可以实现文件的预览和展示功能。我们可以将文件作为MultipartFile对象进行处理,然后将其内容转换为适当的格式进行展示。例如,对于PDF文件,我们可以使用PDF阅读器插件进行展示;对于图片文件,我们可以将其直接展示在网页上。

5. 文件批量上传和处理

在实际应用中,有时候用户需要批量上传多个文件,并对这些文件进行处理。使用MultipartFile接口,我们可以实现文件的批量上传和处理功能。我们可以将多个文件作为一个多部分文件上传请求进行处理,然后对每个文件进行相应的操作。例如,我们可以将多个图片文件批量上传到服务器,并对它们进行压缩、裁剪等处理。

代码

package com.javagpt.back.controller;import com.javagpt.application.context.UserAppContextHolder;
import com.javagpt.application.file.FileApplicationService;
import com.javagpt.application.file.FileDTO;
import com.javagpt.common.annotation.RespSuccess;
import com.javagpt.common.constant.EMConstant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;@Api(tags = "文件接口")
@Slf4j
@RestController
@RequestMapping(EMConstant.API_V1 + "/file")
@RespSuccess
@RequiredArgsConstructor
public class FileController {private final FileApplicationService fileApplicationService;@ApiOperation("通用文件上传")@PostMapping(value = "/uploadFile")public FileDTO uploadFile(@RequestParam("file") MultipartFile multipartFile) throws IOException {Long enterpriseId = UserAppContextHolder.getCurrentUser().getEnterpriseId();FileDTO fileDTO = fileApplicationService.saveFile(enterpriseId, multipartFile);return fileDTO;}//@PreAuthorize("hasAuthority('mp:file:download')")@ApiOperation("下载文件")@GetMapping(value = "/downloadFile")public void download(@RequestParam(value = "id") Long id, HttpServletResponse response) throws IOException {fileApplicationService.downloadFile(response, id, UserAppContextHolder.getCurrentUser().getEnterpriseId());}@ApiOperation("查看文件信息")@GetMapping(value = "/info")public FileDTO fileInfo(@RequestParam(value = "id") Long id) throws IOException {return fileApplicationService.findById(id);}@ApiOperation("下载视频")@GetMapping(value = "/downloadFile2")public void download2(@RequestParam(value = "id") Long id, HttpServletRequest request, HttpServletResponse response) throws IOException {fileApplicationService.downloadVideo(request, response, id, UserAppContextHolder.getCurrentUser().getEnterpriseId());}
}
package com.javagpt.application.file;import com.javagpt.common.exception.BusinessRuntimeException;
import com.javagpt.common.oos.OssService;
import com.javagpt.common.util.ModelUtils;
import com.javagpt.common.util.SpringResponseUtils;
import com.javagpt.file.entity.FileEntity;
import com.javagpt.file.repository.FileRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;import java.io.*;@Service
@Slf4j
@RequiredArgsConstructor
public class FileApplicationService {private final OssService ossService;private final FileRepository fileRepository;public FileDTO findById(Long id) {FileEntity fileEntity = fileRepository.findById(id);return ModelUtils.convert(fileEntity, FileDTO.class);}@Transactionalpublic FileDTO saveFile(Long enterpriseId, MultipartFile file) {FileEntity fileEntity = saveFile(enterpriseId, file, null);return ModelUtils.convert(fileEntity, FileDTO.class);}@Transactionalpublic FileEntity saveFile(Long enterpriseId, MultipartFile file, String fileName) {String originalFilename = file.getOriginalFilename();String name = StringUtils.isBlank(fileName) ? FilenameUtils.getBaseName(originalFilename) : fileName;String suffix = FilenameUtils.getExtension(originalFilename);long size = file.getSize();FileEntity fileEntity = new FileEntity();fileEntity.setName(name).setSuffix(suffix).setSize(size).setEnterpriseId(enterpriseId);fileEntity = fileEntity.save();String key = fileEntity.getPath();InputStream inputStream = null;try {inputStream = file.getInputStream();} catch (IOException e) {log.error("saveFile error:", e);throw BusinessRuntimeException.error("上传文件失败");}ossService.uploadFile(inputStream, key);IOUtils.closeQuietly(inputStream);return fileEntity;}@Transactionalpublic FileEntity saveFile(File file) {long size = file.length();FileEntity fileEntity = new FileEntity();String baseName = FilenameUtils.getBaseName(file.getName());String extension = FilenameUtils.getExtension(file.getName());fileEntity.setName(baseName).setSuffix(extension).setSize(size);fileEntity = fileEntity.save();String key = fileEntity.getPath();FileInputStream inputStream = null;try {inputStream = new FileInputStream(file);ossService.uploadFile(inputStream, key);} catch (FileNotFoundException e) {log.error("saveFile error:", e);throw BusinessRuntimeException.error("上传文件失败");}IOUtils.closeQuietly(inputStream);return fileEntity;}public void downloadFile(HttpServletResponse response, Long fileId, Long enterpriseId) throws IOException {FileEntity fileEntity = fileRepository.findById(fileId);if (fileEntity == null) {throw BusinessRuntimeException.error("无效的文件Id");}String key = fileEntity.getPath();InputStream inputStream = ossService.downloadFile(key);SpringResponseUtils.writeAndFlushResponse(inputStream, response, fileEntity.fileFullName());}public void downloadVideo(HttpServletRequest request, HttpServletResponse response, Long fileId, Long enterpriseId) throws IOException {FileEntity fileEntity = fileRepository.findById(fileId);if (fileEntity == null) {throw BusinessRuntimeException.error("无效的文件Id");}response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");Long fileSize = fileEntity.getSize();long start = 0, end = fileSize - 1;//判断前端需不需要分片下载if (StringUtils.isNotBlank(request.getHeader("Range"))) {response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);String numRange = request.getHeader("Range").replaceAll("bytes=", "");String[] strRange = numRange.split("-");if (strRange.length == 2) {start = Long.parseLong(strRange[0].trim());end = Long.parseLong(strRange[1].trim());//若结束字节超出文件大小 取文件大小if (end > fileSize - 1) {end = fileSize - 1;}} else {//若只给一个长度  开始位置一直到结束start = Long.parseLong(numRange.replaceAll("-", "").trim());}}long rangeLength = end - start + 1;String contentRange = new StringBuffer("bytes ").append(start).append("-").append(end).append("/").append(fileSize).toString();response.setHeader(HttpHeaders.CONTENT_RANGE, contentRange);response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(rangeLength));String key = fileEntity.getPath();InputStream inputStream = ossService.downloadFile2(key, start, end);SpringResponseUtils.writeAndFlushResponse(inputStream, response, fileEntity.fileFullName());}
}

总之,MultipartFile接口在Web应用中具有广泛的应用场景,可以实现文件上传、下载、编辑、预览和批量处理等功能。通过熟练掌握MultipartFile接口的使用方法和技巧,我们可以更加高效地处理文件上传和下载请求,提升Web应用的用户体验和功能性能。

本文由博客一文多发平台 OpenWrite 发布!

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

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

相关文章

数据中台规划与建设方案PPT(建议收藏)

推荐书籍: 《分布式商业生态战略:数字商业新逻辑与企业数字化转型新策略》 书籍介绍: 本书从新时代商业环境出发,紧随市场热点,如元宇宙、Web 3.0、资产数字化、反垄断、要素市场化配置、分布式自治组织(d…

2024年4月13日美团春招实习试题【第二题:最多0的个数】-题目+题解+在线评测【贪心】

2024年4月13日美团春招实习试题【第二题:最多0的个数】-题目题解在线评测【贪心】 题目描述:输入描述输出描述样例 解题思路一:贪心,将所有负数变为正数,然后排序。nums.sort(key lambda x: abs(x))解题思路二:c解题思…

数据仓库作业五:第8章 关联规则挖掘

目录 第8章 关联规则挖掘作业题 第8章 关联规则挖掘 作业题 1、设4-项集 X { a , b , c , d } X\{a,b,c,d\} X{a,b,c,d},试求出由 X X X 导出的所有关联规则。 解: 首先生成项集的所有非空真子集。这包括: { a } , { b } , { c } , {…

UE5集成gRPC

最近有项目需要在UE5里做RPC,对比了thrift、gRPC、rcplib等开源rpc框架,由于习惯使用protobuf,故选择了gRPC。然而,Google出品也是一言难尽啊,最起码编译太繁琐了。 本次使用的gRPC版本为1.62.1,UE5.2&…

基于机器学习的车辆状态异常检测

基于马氏距离的车辆状态异常检测(单一传感器) 基于多元自动编码器的车辆状态异常检测 基于单传感器平滑马氏距离的车辆状态异常检测 工学博士,担任《Mechanical System and Signal Processing》等期刊审稿专家,擅长领域&#xff1…

数据结构详解

数据结构 线性结构 一个有序数据元素的集合其中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的 非线性结构 线性结构的对立面 数组 定义 数组是一种线性数据结构,用于存储相同类型…

java面向对象的封装Triangle

(1)定义三角形类Triangle, * - 声明实例变量a,b,c,代表三角形三条边,全部私有化private, * - 提供每条边的get方法, * - 提供public void setBases(double a, double b, double c):要…

【Redis(3)】深入理解Redis三种高可用方案,以做出明智的选择

通过上一篇文章详细介绍了Redis的持久化方式RDB和AOF配置,这一篇主要介绍Redis的几种高可用方案。 Redis作为一个成熟的远程字典服务,提供了三种常用的高可用设计方案,Redis的每种高可用性方案都各有千秋,选择时需要细致考虑业务…

JavaSE基础:数值比较

数值比较 目录 数值比较 等值判断 和 的区别 重写 equals 方法 数值比较 compareTo 方法 compare 方法 等值判断 Object 类实现了 equals 方法 ,用于比较两个数据元素是否相等。 浮点类型由于精度丢失问题,进行等值判断常出现错误。如果有需求推…

【加密周报】中东“惊雷”炸响币圈!比特币减半成功完成,市场情绪已被提前消化!中美突传USDT重磅消息!

周五(4月19日),比特币经历惊魂一刻,伊朗核设施所处的中部城市伊斯法罕惊传爆炸,叙利亚与伊拉克也都传来爆炸声响,中东全面战争与核武攻击威胁触发加密市场恐慌情绪。比特币一度下探59600美元。但随后伊朗强调核设施未受损&#xf…

组件安全(Solr、Shiro、Log4j、Jackson、FastJson、XStream)

Solr 主要基于HTTP和 Apache Lucene 实现的全文搜索服务器。 特征&#xff1a;图标识别 端口&#xff1a;8393 CVE-2019-0193&#xff08;远程命令执行漏洞&#xff09; 漏洞版本&#xff1a;Apache Solr < 8.2.0 利用条件&#xff1a; Apache Solr 的 DataImportHandler 启…

数据结构_带头双向循环链表

List.h 相较于之前的顺序表和单向链表&#xff0c;双向链表的逻辑结构稍微复杂一些&#xff0c;但是在实现各种接口的时候是很简单的。因为不用找尾&#xff0c;写起来会舒服一点。&#xff08;也可能是因为最近一直在写这个的原因&#xff09; #pragma once #include<std…

二维码门楼牌管理应用平台建设:构建智能社区治理新模式

文章目录 前言一、二维码门楼牌管理应用平台的意义二、走访日志功能的重要性三、走访日志功能的具体应用四、走访日志功能的优势五、结语 前言 在数字化浪潮下&#xff0c;社区管理正面临着前所未有的机遇与挑战。二维码门楼牌管理应用平台的建设&#xff0c;不仅为社区治理提…

代码随想录训练营Day 27|Python|Leetcode|122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

122.买卖股票的最佳时机II 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&#xff0c;然后在 同一天 出售。 返回 你能获…

fastjson转换json时默认将属性第一个字母转小写

描述&#xff1a; 我新建了一个实体类&#xff0c;但是实体类的首字母是大写的&#xff0c;但是使用fastjson后打印的&#xff0c;Json字符串首字母却是小写的&#xff0c;这是fastjson的一个bug 实体类&#xff1a; Json字符串&#xff1a; 解决方法&#xff1a; 一、使…

HoloLens2的Unity应用在电脑上发布成安装包,然后通过wifi安装到设备

一、VS工程中的鼠标右键 二、发布——>创建应用程序包 三、选择【旁加载】 四、选择签名方法&#xff1a; 五、选择和配置包 六、创建完毕 七、网络连接设备 八、登录设备 九、安装app

六边形酷科技特效单页源码

源码介绍 基于canvas画布绘制多个六边形追踪鼠标&#xff0c;科技感的几何图形酷炫动画特效&#xff0c; 单页html源码&#xff0c;可以做网站动态背景&#xff0c;喜欢的朋友可以拿去 效果截图 完整源码 <!doctype html> <html> <head> <meta charset…

基于Kubernetes集群1.27.3构建ElasticSearch-7集群

基于Kubernetes集群构建ES集群 作者:行癫(盗版必究) 一:环境准备 1.Kubernetes集群环境 节点地址Kubernetes-Master10.9.12.206Kubernetes-Node-110.9.12.205Kubernetes-Node-210.9.12.204Kubernetes-Node-310.9.12.203DNS服务器10.9.12.210代理服务器10.9.12.209NFS存储1…

java之逻辑运算符

在java中&#xff0c;逻辑与的表示方法 && 逻辑或的表示方法 || 逻辑非为! 除了逻辑非是一元运算符之外&#xff0c;其他的都是二元运算符。 逻辑运算符的值必须是boolean型 假定两个变量&#xff0c;a和b&#xff0c;true用对表示&#xff0c;fals用错表示 a对&…

项目7-音乐播放器3(删除模块+播放音乐模块设计)

1.播放音乐模块设计 1.1 请求响应设计 请求&#xff1a; { get, /music/get?pathxxx.mp3 } 响应&#xff1a; { 音乐数据本身的字节信息 } 1.2 后端代码 1. Files.readAllBytes(String path) : 读取文件中的所有字节&#xff0c;读入内存 &#xff…