当前位置: 首页 > news >正文

Spring Boot中保存前端上传的图片 - 教程

在Spring Boot中保存前端上传的图片可以通过以下步骤实现:

1. 添加依赖

确保在pom.xml中已包含Spring Web依赖:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

2. 配置文件上传限制

application.properties中设置文件大小限制:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
#====自定义变量======
#文件上传地址
file.upload.dir=uploads/

3. 创建文件上传控制器

package com.hirain.mall.controller
;
import com.hirain.mall.common.ApiRestResponse
;
import jakarta.servlet.http.HttpServletRequest
;
import org.springframework.beans.factory.annotation.Value
;
import org.springframework.web.bind.annotation.PostMapping
;
import org.springframework.web.bind.annotation.RequestMapping
;
import org.springframework.web.bind.annotation.RequestParam
;
import org.springframework.web.bind.annotation.RestController
;
import org.springframework.web.multipart.MultipartFile
;
import java.nio.file.Files
;
import java.nio.file.Path
;
import java.nio.file.Paths
;
import java.util.Map
;
import java.util.UUID
;
@RestController
@RequestMapping
("/images"
)
public
class ImageController {
@Value
("${file.upload.dir}"
) // 从配置文件中读取路径
private String uploadDir;
@PostMapping
("/upload"
)
public ApiRestResponse<
?> uploadImage(
@RequestParam
("image"
) MultipartFile file,
HttpServletRequest request) {
try {
// 创建目录 (如果不存在)
Path uploadPath = Paths.get(uploadDir)
;
if (!Files.exists(uploadPath)
) {
Files.createDirectories(uploadPath)
;
}
// 生成唯一文件名 (避免覆盖)
String originalFileName = file.getOriginalFilename(
)
;
String fileExt = originalFileName.substring(originalFileName.lastIndexOf("."
)
)
;
String newFileName = UUID.randomUUID(
) + fileExt;
// 保存文件
Path targetPath = uploadPath.resolve(newFileName)
;
Files.copy(file.getInputStream(
)
, targetPath)
;
// 生成访问 URL (使用环境信息构建完整URL)
String baseUrl = request.getRequestURL(
).toString(
).replace(request.getRequestURI(
)
, ""
)
;
String imageUrl = baseUrl + "/images/" + newFileName;
return ApiRestResponse.success(Map.of(
"filename"
, newFileName,
"url"
, imageUrl//完成静态资源映射配置后,通过浏览器直接访问该地址即可访问图片
)
)
;
}
catch (Exception e) {
return ApiRestResponse.error(500
,"上传失败: " + e.getMessage(
)
)
;
}
}
}

4.静态资源映射配置类WebConfig

package com.hirain.mall.config
;
import org.springframework.beans.factory.annotation.Value
;
import org.springframework.context.annotation.Configuration
;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
import java.io.File
;
@Configuration
public
class WebConfig
implements WebMvcConfigurer {
@Value
("${file.upload.dir}"
)
private String uploadDir;
@Override
public
void addResourceHandlers(ResourceHandlerRegistry registry) {
// 将真实的上传目录映射为虚拟路径
registry.addResourceHandler("/images/**"
)
.addResourceLocations("file:" + uploadDir + File.separator)
;
}
}

5. 前端调用示例(HTML)

<input type="file" id="imageInput"><button onclick="uploadImage(
)">上传</button>
<script>asyncfunction uploadImage() {const fileInput = document.getElementById('imageInput');const formData =new FormData();formData.append('image', fileInput.files[0]);const response =await fetch('http://localhost:8080/images/upload', {method: 'POST',body: formData});const result =await response.text();console.log(result);}
</script>

6. postman调用示例

在这里插入图片描述

关键点说明:

  1. 文件保存路径

  2. 文件名处理

  3. 异常处理

进阶优化建议:

  1. 添加文件类型校验

    if (!file.getContentType(
    ).startsWith("image/"
    )
    ) {
    return "仅支持图片文件"
    ;
    }
  2. 添加安全限制

  3. 云存储方案

处理流程示意图:

在这里插入图片描述
其中,前端上传图片后,后端保存在本地的流程如下:

前端 → 发送Multipart请求 → Spring控制器 → 验证文件 → 生成唯一文件名 → 保存到本地 → 返回结果

根据实际需求选择本地存储或云存储方案,并注意做好文件类型校验和安全防护措施。

http://www.zskr.cn/news/16367.html

相关文章:

  • Linux--进程概念 - 详解
  • 设计模式——访问者设计模式(行为型) - 实践
  • Unity UI 性能优化终极指南 — Image篇 - 教程
  • HTB Eureka靶机渗透实战 - Spring Boot堆转储与Bash算术注入漏洞利用
  • 实用指南:Python编程基础(四) | if语句
  • 本地Markdown开源知识库选型指南 - 详解
  • 详细介绍:ROS2与Unitree机器人集成指南
  • plexe 通过提示词构建机器学习模型
  • 在AI技术快速实现创意的时代,挖掘游戏开发框架新需求成为关键
  • macOS 编辑字幕
  • [MCP] Register Prompt
  • Software Foundations Vol.I : Coq函数式编程(Basics)
  • CSS - transition 粗浅记忆
  • P4550 收集邮票
  • P1654 OSU!
  • 10/4
  • DynamoDB十年演进:云原生数据库的技术革新
  • NotImplementedError: Cannot convert a symbolic Tensor (lstm/strided_slice:0) to a numpy array.
  • HTML基础学习 - 教程
  • 7_如何构建知识图谱
  • WPF ContentControl Content Binding
  • 盛世华诞 举国同庆|热烈庆祝 LEWISAK 英勇重创消火栓 1 周年!
  • 完整教程:<el-table>构建树形结构
  • CF2115 VP 记录
  • 深入解析:低秩矩阵、奇异值矩阵和正交矩阵
  • POLIR-Society-Philosophy- Hegels 形而上学System Philosophy Dialectics 系统化哲学辩证法: 自由意志+封闭的绝对精神
  • luogu P8816 [CSP-J 2022] 上升点列 题解
  • 集成测试 maestro-我的第一个flow以及第一次云端测试 - 详解
  • 2025 年生物除臭设备厂家最新推荐排行榜:覆盖污水处理厂 / 垃圾中转站等多场景,助力企业精准挑选优质设备
  • 从理念到沙盘:用悟空博弈模拟器点亮人机共治的曙光