基于Spring实现文件上传功能
发布时间 - 2026-01-11 03:03:29 点击率:次本小节你将建立一个可以接受HTTP multi-part 文件的服务。

你将建立一个后台服务来接收文件以及前台页面来上传文件。
要利用servlet容器上传文件,你要注册一个MultipartConfigElement类,以往需要在web.xml 中配置<multipart-config>,
而在这里,你要感谢SpringBoot,一切都为你自动配置好了。
1、新建一个文件上传的Controller:
应用已经包含一些 存储文件 和 从磁盘中加载文件 的类,他们在cn.tiny77.guide05这个包下。我们将会在FileUploadController中用到这些类。
package cn.tiny77.guide05;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller
public class FileUploadController {
private final StorageService storageService;
@Autowired
public FileUploadController(StorageService storageService) {
this.storageService = storageService;
}
@GetMapping("/")
public String listUploadedFiles(Model model) throws IOException {
List<String> paths = storageService.loadAll().map(
path -> MvcUriComponentsBuilder.fromMethodName(FileUploadController.class,
"serveFile", path.getFileName().toString()).build().toString())
.collect(Collectors.toList());
model.addAttribute("files", paths);
return "uploadForm";
}
@GetMapping("/files/{filename:.+}")
@ResponseBody
public ResponseEntity<Resource> serveFile(@PathVariable String filename) {
Resource file = storageService.loadAsResource(filename);
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getFilename() + "\"").body(file);
}
@PostMapping("/")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
storageService.store(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
@ExceptionHandler(StorageFileNotFoundException.class)
public ResponseEntity<?> handleStorageFileNotFound(StorageFileNotFoundException exc) {
return ResponseEntity.notFound().build();
}
}
该类用@Controller注解,因此SpringMvc可以基于它设定相应的路由。每一个@GetMapping和@PostMapping注解将绑定对应的请求参数和请求类型到特定的方法。
GET / 通过StorageService 扫描文件列表并 将他们加载到 Thymeleaf 模板中。它通过MvcUriComponentsBuilder来生成资源文件的连接地址。
GET /files/{filename} 当文件存在时候,将加载文件,并发送文件到浏览器端。通过设置返回头"Content-Disposition"来实现文件的下载。
POST / 接受multi-part文件并将它交给StorageService保存起来。
你需要提供一个服务接口StorageService来帮助Controller操作存储层。接口大致如下
package cn.tiny77.guide05;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.stream.Stream;
public interface StorageService {
void init();
void store(MultipartFile file);
Stream<Path> loadAll();
Path load(String filename);
Resource loadAsResource(String filename);
void deleteAll();
}
以下是接口实现类
package cn.tiny77.guide05;
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;
import java.util.stream.Stream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
@Service
public class FileSystemStorageService implements StorageService {
private final Path rootLocation;
@Autowired
public FileSystemStorageService(StorageProperties properties) {
this.rootLocation = Paths.get(properties.getLocation());
}
@Override
public void store(MultipartFile file) {
String filename = StringUtils.cleanPath(file.getOriginalFilename());
try {
if (file.isEmpty()) {
throw new StorageException("无法保存空文件 " + filename);
}
if (filename.contains("..")) {
// This is a security check
throw new StorageException(
"无权访问该位置 "
+ filename);
}
Files.copy(file.getInputStream(), this.rootLocation.resolve(filename),
StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e) {
throw new StorageException("无法保存文件 " + filename, e);
}
}
@Override
public Stream<Path> loadAll() {
try {
return Files.walk(this.rootLocation, 1)
.filter(path -> !path.equals(this.rootLocation))
.map(path -> this.rootLocation.relativize(path));
}
catch (IOException e) {
throw new StorageException("读取文件异常", e);
}
}
@Override
public Path load(String filename) {
return rootLocation.resolve(filename);
}
@Override
public Resource loadAsResource(String filename) {
try {
Path file = load(filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable()) {
return resource;
}
else {
throw new StorageFileNotFoundException(
"无法读取文件: " + filename);
}
}
catch (MalformedURLException e) {
throw new StorageFileNotFoundException("无法读取文件: " + filename, e);
}
}
@Override
public void deleteAll() {
FileSystemUtils.deleteRecursively(rootLocation.toFile());
}
@Override
public void init() {
try {
Files.createDirectories(rootLocation);
}
catch (IOException e) {
throw new StorageException("初始化存储空间出错", e);
}
}
}
2、建立一个Html页面
这里使用Thymeleaf模板
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:if="${message}">
<h2 th:text="${message}"/>
</div>
<div>
<form method="POST" enctype="multipart/form-data" action="/">
<table>
<tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
<tr><td></td><td><input type="submit" value="Upload" /></td></tr>
</table>
</form>
</div>
<div>
<ul>
<li th:each="file : ${files}">
<a th:href="${file}" rel="external nofollow" th:text="${file}" />
</li>
</ul>
</div>
</body>
</html>
页面主要分为三部分分
- 顶部展示SpringMvc传过来的信息
- 一个提供用户上传文件的表单
- 一个后台提供的文件列表
3、限制上传文件的大小
在文件上传的应用中通常要设置文件大小的,想象一下后台处理的文件如果是5GB,那得多糟糕!在SpringBoot中,我们可以通过属性文件来控制。
新建一个application.properties,代码如下:
spring.http.multipart.max-file-size=128KB #文件总大小不能超过128kb
spring.http.multipart.max-request-size=128KB #请求数据的大小不能超过128kb
4、应用启动函数
package cn.tiny77.guide05;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableConfigurationProperties(StorageProperties.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
CommandLineRunner init(StorageService storageService) {
return (args) -> {
storageService.deleteAll();
storageService.init();
};
}
}
5、运行结果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Spring
# 文件上传
# SpringMVC文件上传 多文件上传实例
# Spring实现文件上传(示例代码)
# 详解SpringBoot文件上传下载和多文件上传(图文)
# jquery.form.js框架实现文件上传功能案例解析(springmvc)
# SpringMVC 文件上传配置
# 多文件上传
# 使用的MultipartFile的实例
# 使用jQuery.form.js/springmvc框架实现文件上传功能
# MyBatis与SpringMVC相结合实现文件上传、下载功能
# springMVC配置环境实现文件上传和下载
# SpringMVC文件上传的配置实例详解
# Spring Boot实现文件上传示例代码
# 上传文件
# 你要
# 加载
# 文件列表
# 你将
# 不能超过
# 新建一个
# 好了
# 为你
# 一切都
# 而在
# 会在
# 我们可以
# 得多
# 将它
# 提供一个
# 建立一个
# 表单
# 来实现
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
在centOS 7安装mysql 5.7的详细教程
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
js实现获取鼠标当前的位置
php在windows下怎么调试_phpwindows环境调试操作说明【操作】
Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全
Laravel如何创建自定义Facades?(详细步骤)
Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】
Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册
深圳网站制作的公司有哪些,dido官方网站?
ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
清除minerd进程的简单方法
高性能网站服务器部署指南:稳定运行与安全配置优化方案
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】
昵图网官方站入口 昵图网素材图库官网入口
Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】
个人网站制作流程图片大全,个人网站如何注销?
在线教育网站制作平台,山西立德教育官网?
如何在阿里云ECS服务器部署织梦CMS网站?
用yum安装MySQLdb模块的步骤方法
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
JavaScript如何实现路由_前端路由原理是什么
Laravel如何使用Vite进行前端资源打包?(配置示例)
Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程
Laravel如何创建自定义Artisan命令?(代码示例)
Laravel如何实现API速率限制?(Rate Limiting教程)
高端云建站费用究竟需要多少预算?
zabbix利用python脚本发送报警邮件的方法
PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环
瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口
IOS倒计时设置UIButton标题title的抖动问题
如何用免费手机建站系统零基础打造专业网站?
Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧
Laravel如何配置和使用缓存?(Redis代码示例)
Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知
Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】
重庆市网站制作公司,重庆招聘网站哪个好?
Linux虚拟化技术教程_KVMQEMU虚拟机安装与调优
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
利用JavaScript实现拖拽改变元素大小
Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议
bootstrap日历插件datetimepicker使用方法

