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;@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 将真实的上传目录映射为虚拟路径registry.addResourceHandler("/images/**").addResourceLocations("file:" + uploadDir + File.separator);}
}

5. 前端调用示例(HTML)

<input type="file" id="imageInput">
<button onclick="uploadImage()">上传</button><script>
async function 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. 文件保存路径

    • 示例中使用相对路径uploads/(项目根目录下)
    • 生产环境建议使用绝对路径(如/var/www/uploads/
  2. 文件名处理

    • 使用时间戳前缀确保唯一性
    • 保留原始文件名后缀(通过file.getOriginalFilename()获取)
  3. 异常处理

    • 捕获IOException处理文件操作异常
    • 返回错误信息给前端

进阶优化建议:

  1. 添加文件类型校验

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

    • 限制文件扩展名(jpg, png等)
    • 使用病毒扫描工具扫描上传文件
  3. 云存储方案

    • 生产环境建议使用云存储(AWS S3, 阿里云OSS等)
    • 示例代码替换为云存储SDK的上传逻辑

处理流程示意图:

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

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

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

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

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

相关文章

应用层协议:HTTP

目录 HTTP&#xff1a;超文本传输协议 1.1 HTTP报文 1.1.1 请求报文 1.1.2 响应报文 1.2 HTTP请求过程和原理 1.2.1 请求过程 1、域名&#xff08;DNS&#xff09;解析 2、建立TCP连接&#xff08;三次握手&#xff09; 3、发送HTTP请求 4、服务器处理请求 5、返回H…

商务合同范本智能审核系统 AI 大模型处理方案

1. 项目概述与目标 目标: 构建一个基于AI大模型的智能合同审核系统,能够自动解析商务合同范本,识别其中的法律风险点(如权责不对等、违约金比例异常、条款模糊、缺失必要条款等),并结合企业内部合规数据库进行实时比对,提供专业的修改建议,大幅提升合同审查的效率和合…

Kafka 消息队列

一、 消息队列 1. 什么是消息队列 消息(Message)是指在应用间传送的数据。消息可以非常简单&#xff0c;比如只包含文本字符串&#xff0c;也可以更复杂&#xff0c;可能包含嵌入对象。消息队列(Message Queue)是一种应用间的通信方式&#xff0c;消息发送后可以立即返回&…

NodeJS全栈WEB3面试题——P3Web3.js / Ethers.js 使用

3.1 Ethers.js 和 Web3.js 的主要区别是什么&#xff1f; 比较点Ethers.jsWeb3.js体积更轻量&#xff0c;适合前端较大&#xff0c;加载慢&#xff0c;适合 Node文档文档简洁、现代化&#xff0c;支持 TypeScript文档丰富&#xff0c;但不够现代化模块化设计高度模块化&#x…

Ubuntu 桌面版忘记账户密码的重置方法

如果你忘记了 Ubuntu 桌面版的用户密码&#xff0c;可以通过进入恢复模式&#xff08;Recovery Mode&#xff09;来重置密码。以下是详细步骤&#xff1a; 一、进入 GRUB 引导菜单 重启计算机&#xff1a;点击关机按钮&#xff0c;选择重启。在启动时按住 Shift 键&#xff1…

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…

【五子棋在线对战】二.项目结构设计 实用工具类模板的实现

项目结构设计 1.项目模块划分2.业务处理模块子模块的划分3.实用工具类模板的实现3.1 日志宏的实现3.2 mysql工具3.3 JsonCpp工具3.4 string-Split工具 && file_util工具 1.项目模块划分 ● 数据管理模块&#xff1a;依托 MySQL 数据库&#xff0c;负责用户数据的存储与…

53 python akshare(获取金融数据)

在金融数据获取与分析领域,AkShare是一个强大且灵活的开源库,它提供了丰富的金融数据接口,覆盖股票、期货、期权、基金、债券、外汇等多个金融市场。AkShare更专注于中国金融市场数据,并且支持从多个数据源获取数据,具有更高的稳定性和更全面的数据覆盖。 一、安装akshar…

蓝桥杯17114 残缺的数字

问题描述 七段码显示器是一种常见的显示数字的电子元件&#xff0c;它由七个发光管组成: 图依次展示了数字 0∼9 用七段码来显示的状态&#xff0c;其中灯管为黄色表示点亮&#xff0c;灰色表示熄灭。根据灯管的亮暗状态&#xff0c;我们可以用一个状态码(状态码是一个 7 位的…

Java观察者模式深度解析:构建松耦合事件驱动系统的艺术

目录 观察者模式基础解析核心结构与实现原理Java内置观察者实现Spring框架中的高级应用典型应用场景与实战案例观察者模式变体与优化常见问题与最佳实践总结与未来展望1. 观察者模式基础解析 1.1 模式定义与核心思想 观察者模式(Observer Pattern)是一种行为型设计模式,它…

NocoBase v1.7.0 正式版发布

原文链接&#xff1a;https://www.nocobase.com/cn/blog/nocobase-1-7-0。 新特性 用户角色并集 角色并集是一种权限管理模式&#xff0c;根据系统设置&#xff0c;系统开发者可以选择使用独立角色、允许角色并集&#xff0c;或者仅使用角色并集&#xff0c;以满足不同的权限…

破解通信难题,modbus转profibus网关在高炉水冲渣系统中稳定好用

基于在高炉水冲渣传动监控系统的工艺背景下,稳联技术Profibus-Modbus网关在控制系统中使支持Profibus协议的设备与支持Modbus RTU协议的设备之间进行通讯协议转换的作用,使得支持不同通讯协议的设备之间能够进行数据传递,并且给出了设计方法.应用Profibus-Modbus总线桥WL-ABD30…

开源是什么?我们为什么要开源?

本片为故事类文章推荐听音频哦 软件自由运动的背景 梦开始的地方 20世纪70年代&#xff0c;软件行业处于早期发展阶段&#xff0c;软件通常与硬件捆绑销售&#xff0c;用户对软件的使用、修改和分发权利非常有限。随着计算机技术的发展和互联网的普及&#xff0c;越来越多的开…

Educational Codeforces Round 179 (Rated for Div. 2)(A-E)

题目链接&#xff1a;Dashboard - Educational Codeforces Round 179 (Rated for Div. 2) - Codeforces A. Energy Crystals 思路 贪心地模拟一下过程很容易就看出来了&#xff0c;每次变成尽可能大的数 1 1 0 -> 1 1 3 -> 3 3 5 -> 5 5 11....我们只需要关注最大…

React Native开发鸿蒙运动健康类应用的项目实践记录

​​项目名称​​&#xff1a;HarmonyFitness - 基于React Native的鸿蒙运动健康应用 ​​技术栈​​&#xff1a;React Native 0.72.5 TypeScript HarmonyOS API ArkTS原生模块 一、环境搭建与项目初始化 ​​双环境配置​​ ​​React Native环境​​&#xff1a; npx re…

Linux --UDP套接字实现简单的网络聊天室

一、Server端的实现 1.1、服务端的初始化 ①、创建套接字&#xff1a; 创建套接字接口&#xff1a; #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket(int domain, int type, int protocol); //1. 这是一个创建套接字的接…

Eureka 高可用集群搭建实战:服务注册与发现的底层原理与避坑指南

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…

Spring Boot应用开发实战

Spring Boot应用开发实战&#xff1a;从零到生产级项目的深度指南 在当今Java生态中&#xff0c;Spring Boot已占据绝对主导地位——据统计&#xff0c;超过75%的新Java项目选择Spring Boot作为开发框架。本文将带您从零开始&#xff0c;深入探索Spring Boot的核心精髓&#xf…

yum更换阿里云的镜像源

步骤 1&#xff1a;备份原有源配置&#xff08;重要&#xff01;&#xff09; sudo mkdir /etc/yum.repos.d/backup sudo mv /etc/yum.repos.d/CentOS-* /etc/yum.repos.d/backup/步骤 2&#xff1a;下载阿里云源配置 sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https:…

【算法训练营Day06】哈希表part2

文章目录 四数相加赎金信三数之和四数之和 四数相加 题目链接&#xff1a;454. 四数相加 II 这个题注意它只需要给出次数&#xff0c;而不是元组。所以我们可以分治。将前两个数组的加和情况使用map存储起来&#xff0c;再将后两个数组的加和情况使用map存储起来&#xff0c;ke…