Spring Boot 文件上传实现详解

news2025/5/12 20:47:31

在项目开发过程中,文件上传是极为常见的功能需求。对于熟悉 Spring MVC 文件上传操作的开发者而言,Spring Boot 中的文件上传与之原理基本相通,只是在依赖管理和配置方式上更为简化。接下来,将详细阐述 Spring Boot 项目中文件上传功能的具体实现步骤。

别再让才华被埋没,别再让项目蒙尘!点击

GitHub 在线专业服务直通车GitHub赋能精灵 - 艾米莉,立即加入这场席卷全球开发者的星光革命!若你有快速提升github Star github 加星数的需求,访问taimili.com还可解锁更多专属服务。现在转发邀请好友组队,在艾米莉平台解锁神秘流量加成,让我们携手点亮开源世界的璀璨星空,实现GitHub star项目涨星的无限可能!

一、项目配置

1. 导入依赖

在 Spring Boot 项目里,若需将文件转存至文件服务器,仅需导入jersey-client依赖,借助它可便捷地与文件服务器进行交互。具体依赖配置如下:

<dependency>

<groupId>com.sun.jersey</groupId>

<artifactId>jersey-client</artifactId>

<version>1.19</version>

</dependency>

2. 配置yml文件

yml文件主要用于配置项目的数据源、MyBatis 等相关信息。相较于常规的 Spring Boot 项目,此处着重修改 MyBatis 的包扫描路径,以此确保 MyBatis 能够精准扫描到数据访问层的接口。同时,采用阿里巴巴的 Druid 连接池来管理数据库连接,其详细配置如下:

 
mybatis:

type-aliases-package: com.aruba.download.bean

spring:

datasource:

# 使用阿里的Druid连接池

type: com.alibaba.druid.pool.DruidDataSource

driver-class-name: com.mysql.cj.jdbc.Driver

# 填写你数据库的url、登录名、密码和数据库名

url: jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

username: root

password: root

druid:

# 连接池的配置信息

# 初始化大小,最小,最大

initial-size: 5

min-idle: 5

maxActive: 20

# 配置获取连接等待超时的时间

maxWait: 60000

# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒

timeBetweenEvictionRunsMillis: 60000

# 配置一个连接在池中最小生存的时间,单位是毫秒

minEvictableIdleTimeMillis: 300000

validationQuery: SELECT 1

testWhileIdle: true

testOnBorrow: false

testOnReturn: false

# 打开PSCache,并且指定每个连接上PSCache的大小

poolPreparedStatements: true

maxPoolPreparedStatementPerConnectionSize: 20

# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙

filters: stat,wall,slf4j

# 通过connectProperties属性来打开mergeSql功能;慢SQL记录

connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000

# 配置DruidStatFilter

web-stat-filter:

enabled: true

url-pattern: "/*"

exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"

# 配置DruidStatViewServlet

stat-view-servlet:

url-pattern: "/druid/*"

# IP白名单(没有配置或者为空,则允许所有访问)

allow: 127.0.0.1,192.168.8.109

# IP黑名单 (存在共同时,deny优先于allow)

deny: 192.168.1.188

# 禁用HTML页面上的“Reset All”功能

reset-enable: false

# 登录名

login-username: admin

# 登录密码

login-password: 123456

上述配置中:

  • mybatis.type-aliases-package用于指定 MyBatis 的实体类扫描包。
  • spring.datasource相关配置负责设置数据库连接信息以及 Druid 连接池的参数,涵盖连接池的初始大小、最大连接数、连接超时时间等内容,同时还对 Druid 的监控和安全相关设置进行了配置。

二、复制代码和资源

完成项目配置后,接下来需要对相关代码和资源进行迁移与调整。

1. Java 代码的复制

在 Spring MVC 中,通常借助 XML 配置文件来配置MapperScanner,实现对数据访问层接口的扫描。而在 Spring Boot 项目里,无需 XML 配置,仅需在 Mapper 层接口上添加@Mapper注解,Spring Boot 便能自动扫描并管理这些接口。示例如下:

 
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper

public interface PlayerMapper {

/**

* 新增一个玩家

* @param player 玩家对象

* @return 受影响的行数,成功插入返回1,否则返回0

*/

Integer addPlayer(Player player);

/**

* 获取所有玩家

* @return 包含所有玩家信息的List集合

*/

List<Player> findAllPlayers();

}

2. 资源文件的复制

Spring Boot 默认将 MyBatis 的映射文件存放在resources目录下的mapper文件夹中。同时,将原有的registerPlayer.jsp页面改为registerPlayer.html,并采用 Thymeleaf 技术进行渲染。修改后的页面主要删除了 JSP 的第一行代码,其他功能逻辑基本保持不变,实现了文件上传及显示进度的功能。具体代码如下:

 
<!DOCTYPE html>

<html>

<head>

<title>Title</title>

<script src="js/jquery-1.10.2.min.js"></script>

<script>

$(function () {

// 为上传按钮绑定点击事件

$("#upload").click(function () {

var imgFile = $("#headImg")[0].files[0];

if (imgFile == undefined) {

alert("请选择文件");

return;

}

console.log(imgFile);

var formdata = new FormData();

formdata.append("img", imgFile);

$.ajax({

type: "post",

data: formdata,

url: "uploadImg.do",

processData: false,

contentType: false,

success: function (ret) {

console.log(ret);

alert(ret.msg);

// 更新页面头像显示

$("#head").attr("src", ret.filepath);

$("#filetypeInput").val(ret.filetype);

$("#photoInput").val(ret.filepath);

},

xhr: function () {

var xhr = new XMLHttpRequest();

// 监听文件上传进度

xhr.upload.addEventListener('progress', function (e) {

var progressRate = (e.loaded / e.total) * 100 + '%';

$('.progress > div').css('width', progressRate );

});

return xhr;

}

});

});

});

</script>

<style>

#head {

width: 200px;

height: 200px;

}

.progress {

width: 200px;

height: 10px;

border: 1px solid #ccc;

border-radius: 10px;

margin: 10px 0px;

overflow: hidden;

}

/* 初始状态设置进度条宽度为0px */

.progress > div {

width: 0px;

height: 100%;

background-color: yellowgreen;

transition: all .3s ease;

}

</style>

</head>

<body>

<form action="registerPlayer.do">

<p>用户名:<input type="text" name="name"></p>

<p>密码:<input type="password" name="password"></p>

<p>昵称:<input type="text" name="nickname"></p>

<p>头像:<input id="headImg" type="file">

<input type="button" id="upload" value="上传文件">

</p>

<div class="progress">

<div></div>

</div>

<p><img id="head" alt="未选择图片"></p>

<input id="filetypeInput" type="hidden" name="filetype">

<input id="photoInput" type="hidden" name="photo">

<p><input type="submit" value="注册"></p>

</form>

</body>

</html>

3. Controller 层新增跳转页面的处理单元

为实现正确跳转到registerPlayer.html页面,需在 Controller 层添加对应的处理方法,通过@RequestMapping注解映射请求路径,并返回页面名称。示例代码如下:


import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class FileUploadController {

@RequestMapping("registerPlayer")

public String register() {

return "registerPlayer";

}

}

三、同步上传

前面实现的是文件的异步上传,即通过单独的接口处理文件上传操作。而同步上传是指在提交表单时,一次性上传多个文件以及其他请求参数。

1. 修改 form 表单

将表单的action属性修改为registerPlayer2.do,并设置enctype="multipart/form-data",以支持文件上传。同时,添加多个文件输入框,并去除上传按钮,使文件与其他表单数据一同提交。修改后的表单代码如下:

 
<form action="registerPlayer2.do" method="post" enctype="multipart/form-data">

<p>用户名:<input type="text" name="name"></p>

<p>密码:<input type="password" name="password"></p>

<p>昵称:<input type="text" name="nickname"></p>

<p>头像:

<input id="headImg" name="photo1" type="file">

<input id="headImg2" name="photo2" type="file" multiple>

</p>

<div class="progress">

<div></div>

</div>

<p><img id="head" alt="未选择图片"></p>

<input id="filetypeInput" type="hidden" name="filetype">

<input id="photoInput" type="hidden" name="photo">

<p><input type="submit" value="注册"></p>

</form>

2. Controller 层处理

在 Controller 层的处理方法中,使用MultipartFile类型来接收上传的文件。@RequestParam注解用于指定接收的参数名称,对于多个文件,可使用MultipartFile[]数组来接收。示例代码如下:


import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.multipart.MultipartFile;

@Controller

public class FileUploadController {

@RequestMapping("registerPlayer2.do")

@ResponseBody

public String register2(Player player,

@RequestParam("photo1") MultipartFile head,

@RequestParam("photo2") MultipartFile[] photos) {

// 处理文件上传逻辑,例如保存文件到指定位置、更新数据库等

// 此处省略具体实现代码

return "文件上传成功";

}

}

通过以上步骤,便完成了 Spring Boot 项目中文件上传功能的实现,涵盖异步上传和同步上传两种方式。在实际项目中,可依据具体需求对代码进行进一步优化与扩展,如添加文件格式校验、文件大小限制等功能 。

如果你还希望添加更多内容,比如详细的代码解释、案例拓展,或者对现有内容的格式、表述进行调整,欢迎随时告诉我。

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

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

相关文章

查看单元测试覆盖率

文章目录 1、POM文件配置2、编写单元测试3、执行单元测试4、查看单元测试覆盖率 1、POM文件配置 pom文件配置jacoco插件 <!-- 生成JaCoCo覆盖率数据插件 --> <plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artif…

基于SpringBoot的在线教育管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

C# 方法(方法重载)

本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 方法重载 一个类中可以有多个…

3、食品包装控制系统 - /自动化与控制组件/food-packaging-control

76个工业组件库示例汇总 食品包装线控制系统 这是一个用于食品包装线控制系统的自定义组件&#xff0c;提供了食品包装生产线的可视化监控与控制界面。组件采用工业风格设计&#xff0c;包含生产流程控制、实时数据监控和逻辑编程三个主要功能区域。 功能特点 工业风格UI设…

初始图形学(7)

上一章完成了相机类的实现&#xff0c;对之前所学的内容进行了封装与整理&#xff0c;现在要学习新的内容。 抗锯齿 我们放大之前渲染的图片&#xff0c;往往会发现我们渲染的图像边缘有尖锐的"阶梯"性质。这种阶梯状被称为"锯齿"。当真实的相机拍照时&a…

线程的一些事(2)

在java中&#xff0c;线程的终止&#xff0c;是一种“软性”操作&#xff0c;必须要对应的线程配合&#xff0c;才能把终止落实下去 然而&#xff0c;系统原生的api其实还提供了&#xff0c;强制终止线程的操作&#xff0c;无论线程执行到哪&#xff0c;都能强行把这个线程干掉…

使用lldb看看Rust的HashMap

目录 前言 正文 读取桶的状态 获取键值对 键值对的指针地址 此时&#xff0c;读取数据 读取索引4的键值对 多添加几个键值对 使用i32作为键&#xff0c;&str作为值 使用i32作为键&#xff0c;String作为值 前言 前面使用ldb看了看不同的类型&#xff0c;这篇再使用…

2025最新免费视频号下载工具!支持Win/Mac,一键解析原画质+封面

软件介绍 适用于Windows 2025 最新5月蝴蝶视频号下载工具&#xff0c;免费使用&#xff0c;无广告且免费&#xff0c;支持对原视频和封面进行解析下载&#xff0c;亲测可用&#xff0c;现在很多工具都失效了&#xff0c;难得的几款下载视频号工具&#xff0c;大家且用且珍…

Newton GPU 机器人仿真器入门教程(零)— NVIDIA、DeepMind、Disney 联合推出

系列文章目录 目录 系列文章目录 前言 一、快速入门 1.1 实时渲染 1.2 USD 渲染 1.3 示例&#xff1a;创建一个粒子链 二、重要概念 三、API 参考 3.1 求解器 3.1.1 XPBD 求解器 3.1.2 VBD 求解器 3.1.3 MuJoCo 求解器 3.2 关节控制模式 四、Newton 集成 4.1 Is…

【C++】学习、项目时Debug总结

这里写目录标题 1. 内存问题1.1. 内存泄漏1.1.1. 内存泄漏案例检查方法1.1.2. 主线程提前退出导致【控】1.1.3. PostThreadMessage失败导致的内存泄漏**【控】**1.1.4. SendMessage 时关闭客户端【控】1.1.5. 线程机制导致【**控】**1.1.6. exit&#xff08;0&#xff09;导致【…

26考研——中央处理器_指令流水线_指令流水线的基本概念 流水线的基本实现(5)

408答疑 文章目录 六、指令流水线指令流水线的基本概念流水线的基本实现流水线设计的原则流水线的逻辑结构流水线的时空图表示 八、参考资料鲍鱼科技课件26王道考研书 六、指令流水线 前面介绍的指令都是在单周期处理机中采用串行方法执行的&#xff0c;同一时刻 CPU 中只有一…

AI Agent-基础认知与架构解析

定义 AI Agent 可以理解为一种具备感知、决策和行动能力的智能实体&#xff0c;能够在复杂的环境中自主运行&#xff0c;并根据环境变化动态调整自身行为&#xff0c;以实现特定目标。与传统的人工智能程序相比&#xff0c;AI Agent 具有更强的自主性、交互性和适应性。它不仅能…

C语言--字符函数

C语言--字符函数 一、字符函数1.1 iscntrl1.2 isspace1.3 isdigit1.4 isxdigit1.5 islower1.6 isupper1.7 isalpha1.8 isalnum1.9 ispunct1.10 isgraph1.11 isprint 在编程的过程中&#xff0c;我们会经常处理字符&#xff0c;为了方便操作&#xff0c;C语言标准库中提供了一系…

菜鸟之路Day30一一MySQL之DMLDQL

菜鸟之路Day30一一MySQL之DML&DQL 作者&#xff1a;blue 时间&#xff1a;2025.5.8 文章目录 菜鸟之路Day30一一MySQL之DML&DQL一.DML0.概述1.插入语句&#xff08;insert&#xff09;2.更新语句&#xff08;update&#xff09;3.删除语句&#xff08;delete&#xf…

基 LabVIEW 的多轴电机控制系统

在工业自动化蓬勃发展的当下&#xff0c;多轴伺服电机控制系统的重要性与日俱增&#xff0c;广泛应用于众多领域。下面围绕基于 LabVIEW 开发的多轴伺服电机控制系统展开&#xff0c;详细阐述其应用情况。 一、应用领域与场景 在 3D 打印领域&#xff0c;该系统精确操控打印头…

《Go小技巧易错点100例》第三十二篇

本期分享&#xff1a; 1.sync.Map的原理和使用方式 2.实现有序的Map sync.Map的原理和使用方式 sync.Map的底层结构是通过读写分离和无锁读设计实现高并发安全&#xff1a; 1&#xff09;双存储结构&#xff1a; 包含原子化的 read&#xff08;只读缓存&#xff0c;无锁快…

需求分析阶段测试工程师主要做哪些事情

在软件测试需求分析阶段&#xff0c;主要围绕确定测试范围、明确测试目标、细化测试内容等方面开展工作&#xff0c;为后续测试计划的制定、测试用例的设计以及测试执行提供清晰、准确的依据。以下是该阶段具体要做的事情&#xff1a; 1. 需求收集与整理 收集需求文档&#x…

项目模拟实现消息队列第二天

消息应答的模式 1.自动应答: 消费者把这个消息取走了&#xff0c;就算是应答了&#xff08;相当于没有应答) 2.手动应答: basicAck方法属于手动应答(消费者需要主动调用这个api进行应答) 小结 1.需要实现生产者,broker server&#xff0c;消费者这三个部分的 2.针对生产者和消费…

5.Redission

5.1 前文锁问题 基于 setnx 实现的分布式锁存在下面的问题&#xff1a; 重入问题&#xff1a;重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中&#xff0c;可重入锁的意义在于防止死锁&#xff0c;比如 HashTable 这样的代码中&#xff0c;他的方法都是使用 sync…

dify 部署后docker 配置文件修改

1&#xff1a;修改 复制 ./dify/docker/.env.example ./dify/docker/.env 添加一下内容 # 启用自定义模型 CUSTOM_MODEL_ENABLEDtrue# 将OLLAMA_API_BASE_URL 改为宿主机的物理ip OLLAMA_API_BASE_URLhttp://192.168.72.8:11434# vllm 的 OPENAI的兼容 API 地址 CUSTOM_MODE…