Spring Boot项目中实现文件的上传、下载和预览功能
在Spring Boot项目中实现文件的上传、下载和预览功能,可以通过使用Spring MVC的MultipartFile接口来处理文件上传,并使用HttpServletResponse或Resource来实现文件下载和预览。下面是如何实现这些功能的完整示例。
1. 引入依赖
确保在pom.xml中引入了Spring Boot的相关依赖。通常情况下,Spring Boot Starter Web已经包含了必要的依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. 创建文件上传、下载和预览的Controller
你可以创建一个FileController来处理文件的上传、下载和预览。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;@Controller
@RequestMapping("/files")
public class FileController {// 文件保存路径(可以通过配置文件进行配置)@Value("${file.upload-dir}")private String fileUploadDir;// 文件上传@PostMapping("/upload")@ResponseBodypublic String uploadFile(@RequestParam("file") MultipartFile file) throws IOException {// 获取文件名并且保存文件String fileName = file.getOriginalFilename();Path targetLocation = Paths.get(fileUploadDir).resolve(fileName);Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);// 返回文件下载的URLString fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath().path("/files/download/").path(fileName).toUriString();return "File uploaded successfully: " + fileDownloadUri;}// 文件下载@GetMapping("/download/{fileName}")public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) throws MalformedURLException {Path filePath = Paths.get(fileUploadDir).resolve(fileName).normalize();Resource resource = new UrlResource(filePath.toUri());if (!resource.exists()) {return ResponseEntity.notFound().build();}return ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM).header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"").body(resource);}// 文件预览(主要针对图片、PDF等可以直接在浏览器中显示的文件)@GetMapping("/preview/{fileName}")public ResponseEntity<Resource> previewFile(@PathVariable String fileName) throws MalformedURLException {Path filePath = Paths.get(fileUploadDir).resolve(fileName).normalize();Resource resource = new UrlResource(filePath.toUri());if (!resource.exists()) {return ResponseEntity.notFound().build();}String contentType = "application/octet-stream";try {contentType = Files.probeContentType(filePath);} catch (IOException e) {e.printStackTrace();}return ResponseEntity.ok().contentType(MediaType.parseMediaType(contentType)).body(resource);}
}
3. 配置文件上传目录
在application.properties或application.yml中配置文件的上传路径:
file.upload-dir=C:/uploads
或者使用application.yml:
file:upload-dir: C:/uploads
你可以将路径配置为你项目的目录,也可以指定到服务器的某个位置。
4. 创建上传目录
确保在你的系统上已经创建了配置文件中指定的上传目录,比如C:/uploads。如果没有创建,可以通过代码在项目启动时自动创建:
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;@Component
public class FileUploadDirectoryInitializer implements CommandLineRunner {@Value("${file.upload-dir}")private String fileUploadDir;@Overridepublic void run(String... args) throws Exception {Path uploadPath = Paths.get(fileUploadDir);if (!Files.exists(uploadPath)) {Files.createDirectories(uploadPath);}}
}
5. 测试上传、下载和预览
5.1 文件上传
你可以使用Postman、cURL或者前端页面来测试文件上传功能。上传文件的URL为:
POST http://localhost:8080/files/upload
参数名称为file。
5.2 文件下载
你可以通过以下URL下载文件:
GET http://localhost:8080/files/download/{fileName}
其中{fileName}是文件的名称。
5.3 文件预览
你可以通过以下URL预览文件(如图片或PDF):
GET http://localhost:8080/files/preview/{fileName}
6. 处理大文件上传
对于大文件上传,Spring Boot默认的最大上传文件大小可能不满足需求,可以通过以下配置进行调整:
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
或者在application.yml中:
spring:servlet:multipart:max-file-size: 100MBmax-request-size: 100MB
7. 文件预览类型支持
通常情况下,浏览器支持预览的文件类型包括图片(如jpeg、png)、PDF、文本文件等。如果文件类型不被浏览器支持,通常可以通过文件下载的方式处理。
8. 文件删除功能(可选)
你也可以添加一个删除文件的接口,来删除已上传的文件:
// 文件删除
@DeleteMapping("/delete/{fileName}")
@ResponseBody
public String deleteFile(@PathVariable String fileName) throws IOException {Path filePath = Paths.get(fileUploadDir).resolve(fileName).normalize();Files.deleteIfExists(filePath);return "File deleted successfully";
}
相关文章:
Spring Boot项目中实现文件的上传、下载和预览功能
在Spring Boot项目中实现文件的上传、下载和预览功能,可以通过使用Spring MVC的MultipartFile接口来处理文件上传,并使用HttpServletResponse或Resource来实现文件下载和预览。下面是如何实现这些功能的完整示例。 1. 引入依赖 确保在pom.xml中引入了S…...
【JAVA入门】Day21 - 时间类
【JAVA入门】Day21 - 时间类 文章目录 【JAVA入门】Day21 - 时间类一、JDK7前的时间相关类1.1 Date1.2 SimpleDateFormat1.3 Calendar 二、JDK8新增的时间相关类2.1 Date 相关类2.1.1 ZoneId 时区2.1.2 Instant 时间戳2.1.3 ZoneDateTime 带时区的时间 2.2 DateTimeFormat 相关…...
SQL server数据库备份和还原
新手小白都懂的sql server数据库备份和还原 一、备份 1.打开sql server数据库找到 2.展开找到对应的数据库文件 鼠标右击—任务–备份 3.复制名称 4.复制完点击添加 5.点击添加完之后再次点击查找路径 6.分别两个路径 原路径和新路径 (新路径是找到原路径新建了一…...
B站搜索建库架构优化实践
前言 搜索是B站的重要基础功能,需要对包括视频、评论、图文等海量的站内优质资源建立索引,处理来自用户每日数亿的检索请求。离线索引数据的正确、高效产出是搜索业务的基础。我们在这里分享搜索离线架构整体的改造实践:从周期长,…...
XSS反射实战
目录 1.XSS向量编码 2.xss靶场训练(easy) 2.1第一关 2.2第二关 方法一 方法二 2.3第三关 2.4第四关 2.5第五关 2.6第六关 2.7第七关 第一种方法: 第二种方法: 第三个方法: 2.8第八关 1.XSS向量编码 &…...
远程消息传递的艺术:NSDistantObject在Objective-C中的妙用
标题:远程消息传递的艺术:NSDistantObject在Objective-C中的妙用 引言 在Objective-C的丰富生态中,NSDistantObject扮演着至关重要的角色,特别是在处理分布式系统中的远程消息传递。它允许对象之间跨越不同地址空间进行通信&…...
指向派生类的基类指针、强转为 void* 再转为基类指针、此时调用虚函数会发生什么?
指向派生类的基类指针、强转为 void* 再转为基类指针、此时调用虚函数会发生什么? 1、无论指针类型怎么转,类对象内存没有发生任何变化,还是vfptr指向虚函数表,下面是成员变量,这在编译阶段就已经确定好了;…...
操作系统(Linux实战)-进程创建、同步与锁、通信、调度算法-学习笔记
1. 进程的基础概念 1.1 进程是什么? 定义: 进程是操作系统管理的一个程序实例。它包含程序代码及其当前活动的状态。每个进程有自己的内存地址空间,拥有独立的栈、堆、全局变量等。操作系统通过进程来分配资源(如 CPU 时间、内…...
react的setState中为什么不能用++?
背景: 在使用react的过程中产生了一些困惑,handleClick函数的功能是记录点击次数,handleClick函数被绑定到按钮中,每点击一次将通过this.state.counter将累计的点击次数显示在页面上 困惑: 为什么不能直接写prevStat…...
2.2算法的时间复杂度与空间复杂度——经典OJ
本博客的OJ标题均已插入超链接,点击可直接跳转~ 一、消失的数字 1、题目描述 数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗? 2、题目分析 (1)numsS…...
【CentOS 】DHCP 更改为静态 IP 地址并且遇到无法联网
文章目录 引言解决方式标题1. **编辑网络配置文件**:标题2. **确保配置文件包含以下内容**:特别注意 标题3. **重启网络服务**:标题4. **检查配置是否生效**:标题5. **测试网络连接**:标题6. **检查路由表**࿱…...
Linux 操作系统 --- 信号
序言 在本篇内容中,将为大家介绍在操作系统中的一个重要的机制 — 信号。大家可能感到疑惑,好像我在使用 Linux 的过程中并没有接触过信号,这是啥呀?其实我们经常遇到过,当我们运行的进程当进程尝试访问非法内存地址时…...
黑马前端——days09_css
案例 1 页面框架文件 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compati…...
【Python爬虫】技术深度探索与实践
目录 引言 第一部分:Python爬虫基础 1.1 网络基础 1.2 Python爬虫基本流程 第二部分:进阶技术 2.1 动态网页抓取 2.2 异步编程与并发 2.3 反爬虫机制与应对 第三部分:实践案例 第四部分:法律与道德考量 第五部分&#x…...
智启万象|挖掘广告变现潜力,保障支付安全便捷
谷歌致力于为开发者提供 先进的广告变现与支付解决方案 一起回顾 2024 Google 开发者大会 了解如何利用谷歌最新工具和功能 提高变现收入,优化用户体验,保障交易安全 让变现更上一层楼 广告检查器是谷歌 AdMob 平台最新推出的高级测试工具,开…...
函数递归,匿名、内置行数,模块和包,开发规范
一、递归与二分法 一)递归 1、递归调用的定义 递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身 2、递归分为两类:直接与间接 #直接 def func():print(from func)func()func() # 间接 def foo():print(from foo)bar…...
Springboot3 整合swagger
一、pom.xml <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-api</artifactId><version>2.1.0</version></dependency> 二、application.yml # SpringDoc配置 # springdoc:swa…...
查看同一网段内所有设备的ip
使用命令提示符(CMD)进行扫描 查看本机IP地址 首先通过 ipconfig /all 命令查看本机的IP地址,确定你的网段,例如 192.168.1.。 Ping网段内每个IP地址 接着使用循环命令: for /L %i IN (1,1,254) DO ping -w 1 -n …...
Spark MLlib 特征工程(上)
文章目录 Spark MLlib 特征工程(上)特征工程预处理 Encoding:StringIndexer特征构建:VectorAssembler特征选择:ChiSqSelector归一化:MinMaxScaler模型训练总结Spark MLlib 特征工程(上) 前面我们一起构建了一个简单的线性回归模型,来预测美国爱荷华州的房价。从模型效果来…...
《SPSS零基础入门教程》学习笔记——03.变量的统计描述
文章目录 3.1 连续变量(1)集中趋势(2)离散趋势(3)分布特征 3.2 分类变量(1)单个分类变量(2)多个分类变量 3.1 连续变量 (1)集中趋势 …...
Wan2.1-umt5能力展示:模拟计算机组成原理教学问答
Wan2.1-umt5能力展示:模拟计算机组成原理教学问答 最近在尝试用大模型辅助教学,发现了一个挺有意思的镜像——Wan2.1-umt5。它不像常见的聊天模型,更像是一个专门为理解和生成专业内容设计的“专家”。我突发奇想,让它扮演了一回…...
RAG开发
LangChain通用提示词模板:from langchain_core.prompts import PromptTemplate from langchain_community.llms import Tongyiprompt_template PromptTemplate.from_template("我的邻居姓{lastname},刚生了{gender}" )prompt_template.format(lastname …...
参数估计实战:从置信区间构建到样本量计算的完整指南
1. 参数估计的核心逻辑:从抽样到推断 第一次接触参数估计时,我盯着那个95%置信区间看了半小时——它既不像天气预报的降水概率,也不像考试分数的百分比排名。后来在分析用户行为数据时才恍然大悟:参数估计本质是用样本数据给总体参…...
大一大二最容易忽视的一张“证书”,却悄悄决定了很多人的未来
很多大学生到了大三才突然发现一件事:有些机会,原来早在大一大二就已经埋好了门槛。比如——英语四六级。保研、考研复试、国企网申、研究生免修英语、甚至一些实习岗位筛选,很多时候都会看到同一行字:CET-4 / CET-6 成绩这张证书…...
跨平台软件兼容方案全解析:从痛点到完美体验的技术实践
跨平台软件兼容方案全解析:从痛点到完美体验的技术实践 【免费下载链接】deepin-wine 【deepin源移植】Debian/Ubuntu上最快的QQ/微信安装方式 项目地址: https://gitcode.com/gh_mirrors/de/deepin-wine 在数字化办公与娱乐日益融合的今天,跨平台…...
2026年专业金属链板输送带服务哪家强?TOP排名为你揭晓!
家人们,在工业生产领域,金属链板输送带那可是相当重要的设备,它的质量和服务直接影响着生产效率。今天咱就来聊聊 2026 年专业金属链板输送带服务的那些事儿,给大家揭晓一下排名情况,顺便看看哪家更值得咱们选择。冲突…...
Windows 内网 Web 服务穿透方案推荐
Windows 内网 Web 服务穿透方案推荐 面向场景:内网机器为 Windows,需从公网或外网访问内网 HTTP/HTTPS Web 服务;优先选择相对不易被误报、来源清晰、可审计的方案。 关于「报毒」的说明 穿透类软件常被启发式引擎标为「风险/可疑」…...
MATLAB Simulink代码生成全流程详解:涵盖环境配置、参数与信号配置、函数名配置、数...
matlab simulink代码生成 包括:环境配置,参数与信号配置,函数名配置,数据管理,代码生成,以及代码优化等 文档63页把Simulink模型变成可烧录的C代码,这事儿听起来挺玄乎,但只要你踩过…...
边缘计算与 AI 结合:奥尔特云低功耗边缘算力设备
这款高性能边缘智能算力设备,搭载16T算力AI处理器,以高性能、低功耗、易扩展为核心优势,为用户提供一站式智能化解决方案。设备内置人脸、视频结构化等基础算法,可扩展工业、矿山、能源、园区、城管、无人机巡检等行业专用算法包&…...
告别Keil!用VSCode+EIDE插件打造你的STM32开发环境(附ST-LINK V2避坑指南)
从Keil到VSCode:打造高效STM32开发环境的完整指南 在嵌入式开发领域,Keil MDK长期以来一直是STM32开发的主流工具,但它的封闭性、高昂的授权费用和略显陈旧的用户界面让越来越多的开发者开始寻找替代方案。Visual Studio Code(VSC…...
