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

图片上传的util和使用

图片上传的util

package com.ruoyi.web.controller.common.utils;import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.io.File;
import java.io.IOException;
import java.util.UUID;public class LocalUploadImageUtils{/*** 上传图片到本地服务器,文件名自定义* @param file 图片文件* @param fileName 自定义文件名* @return 文件访问路径*/public static String uploadFile(MultipartFile file, String fileName) {String finalPath = ConfigFileMessageUtils.IMAGE_ALL_DIR  + fileName;String url = "http://"+ ConfigFileMessageUtils.LOCAL_IP+ ":"+ ConfigFileMessageUtils.SERVER_PORT + "/"+ ConfigFileMessageUtils.IMAGE_DIR_NAME + "/"+ fileName;boolean flag = upload(file, finalPath);if (!flag) {throw new RuntimeException("文件上传失败");}return url;}/*** 为文件名添加前缀c* @param fix 需添加的前缀* @param fileName 文件名* @return 新的文件名*/public static String addFixForFileName(String fix, String fileName) {return fix + getFileSuffix(fileName);}/*** 上传文件到服务器* @param file 需要上传的文件* @param finalPath 文件存放的服务器路径* @return 上传成功返回true,失败返回false*/private static boolean upload(MultipartFile file, String finalPath){File dest = new File(finalPath);//判断文件父目录是否存在if(!dest.getParentFile().exists()){dest.getParentFile().mkdirs();}//上传文件到服务器,相当于将内存的文件输出到服务器,OutputStream,需要try....catch....try {//保存文件//transferTo(dest)方法将上传文件写到服务器上指定的文件file.transferTo(dest);return true;} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();return false;}}private static String getNewFileNameByUuid(String fileName) {return getUUID() + getFileSuffix(fileName);}private static String getUUID(){return UUID.randomUUID().toString().replace("-", "") ;}private static String getFileSuffix(String fileName){return fileName.substring(fileName.lastIndexOf("."));}}/*** 读取图片所需基本信息*/
@Component
class ConfigFileMessageUtils implements InitializingBean {@Value("${server.port}")private String serverPort;/*** 本机IP地址*/public static String LOCAL_IP;/*** 本机服务器端口号*/public static String SERVER_PORT;/*** 保存图片目录名,默认resources/static下*/public static String IMAGE_DIR_NAME = "file";/*** 图片存放的全路径名*/public static String IMAGE_ALL_DIR;/*** 该方法在服务器加载时被调用* @throws Exception*/@Overridepublic void afterPropertiesSet() throws Exception {SERVER_PORT = this.serverPort;LOCAL_IP = "localhost";IMAGE_ALL_DIR = System.getProperty("user.dir") + "/src/main/resources/static/" + IMAGE_DIR_NAME + "/";}
}/*** 释放static下保存文件的目录可被访问*/
@Configuration
class ImageWebMvcConfigurerAdapter implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry){//访问映射,请求放行处理registry.addResourceHandler(""+ ConfigFileMessageUtils.IMAGE_DIR_NAME+"/**").addResourceLocations("file:"+ ConfigFileMessageUtils.IMAGE_ALL_DIR);registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}
}

代码解析

图片上传实现解析

这个代码实现了基于Spring框架的本地图片上传功能,主要包含三个部分:上传工具类、配置类和静态资源访问配置。下面我将详细解析其实现原理和工作流程。

1. 核心组件分析

1.1 LocalUploadImageUtils(上传工具类)

这是图片上传的核心工具类,提供以下功能:

  • uploadFile: 主上传方法,接收文件对象和自定义文件名
  • upload: 实际执行文件存储操作
  • 文件名处理工具方法:
    • addFixForFileName: 为文件名添加前缀
    • getNewFileNameByUuid: 生成UUID文件名
    • getFileSuffix: 获取文件后缀名

1.2 ConfigFileMessageUtils(配置类)

负责读取和存储上传相关的配置信息:

  • 使用@Value注入服务器端口
  • 定义静态常量存储配置信息
  • 通过InitializingBean接口在初始化时设置静态变量

1.3 ImageWebMvcConfigurerAdapter(资源访问配置)

配置静态资源访问规则,使上传的图片可以通过HTTP访问

2. 上传流程详解

2.1 上传步骤

  1. 接收文件:通过MultipartFile接收前端上传的文件
  2. 构建存储路径
    • 使用ConfigFileMessageUtils.IMAGE_ALL_DIR获取基础存储目录
    • 拼接自定义文件名形成完整存储路径
  3. 构建访问URL
    • 格式:http://{IP}:{PORT}/{IMAGE_DIR_NAME}/{filename}
  4. 实际存储
    • 检查父目录是否存在,不存在则创建
    • 使用transferTo()方法将文件写入目标位置
  5. 返回访问URL:供前端使用

2.2 关键代码解析

public static String uploadFile(MultipartFile file, String fileName) {// 构建存储路径String finalPath = ConfigFileMessageUtils.IMAGE_ALL_DIR + fileName;// 构建访问URLString url = "http://" + ConfigFileMessageUtils.LOCAL_IP + ":" + ConfigFileMessageUtils.SERVER_PORT + "/" + ConfigFileMessageUtils.IMAGE_DIR_NAME + "/" + fileName;// 执行上传boolean flag = upload(file, finalPath);if (!flag) {throw new RuntimeException("文件上传失败");}return url;
}

3. 静态资源访问机制

通过WebMvcConfigurer配置静态资源映射:

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){// 映射上传目录到URL路径registry.addResourceHandler(ConfigFileMessageUtils.IMAGE_DIR_NAME+"/**").addResourceLocations("file:"+ConfigFileMessageUtils.IMAGE_ALL_DIR);
}

这样配置后,存储在IMAGE_ALL_DIR目录下的文件可以通过/file/文件名的URL访问。

4. 代码特点与改进建议

4.1 优点

  • 结构清晰,职责分离
  • 支持自定义文件名
  • 自动创建不存在的目录
  • 提供完整的访问URL返回

图片上传的使用部分

  @PostMapping("/uploadAvatar")public ApiResult uploadAvatar(@RequestParam("file") MultipartFile file,@RequestParam("userId") Long userId) {try {// 1. 生成唯一文件名(例如:UUID + 后缀)String originalFilename = file.getOriginalFilename();String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));String fileName = UUID.randomUUID().toString().replace("-", "") + fileExtension;// 2. 上传文件到服务器(调用工具类)String avatarUrl = LocalUploadImageUtils.uploadFile(file, fileName);// 3. 更新用户头像路径MyUser user = myUserService.selectMyUserByUserId(userId);if (user == null) {return new ApiResult<>(0, "用户不存在", null);}user.setAvatarUrl(avatarUrl);myUserService.updateMyUser(user);return new ApiResult<>(1, "头像上传成功", avatarUrl);} catch (Exception e) {return new ApiResult<>(0, "头像上传失败:" + e.getMessage(), null);}}

图片上传调用流程

图片上传与用户头像更新实现原理分析

这个uploadAvatar方法结合了你之前提供的LocalUploadImageUtils工具类,实现了完整的用户头像上传和更新流程。下面我将详细解析其工作原理和实现机制。

1. 整体流程

  1. 前端提交:上传文件(头像图片)和用户ID
  2. 后端处理
    • 生成唯一文件名
    • 保存文件到服务器本地
    • 更新数据库中的用户头像URL
  3. 返回结果:包含操作状态和头像访问URL

2. 核心代码解析

2.1 方法签名

@PostMapping("/uploadAvatar")
public ApiResult uploadAvatar(@RequestParam("file") MultipartFile file,  // 接收上传的文件@RequestParam("userId") Long userId       // 接收用户ID
)
  • 使用@PostMapping处理HTTP POST请求
  • @RequestParam接收表单数据中的文件和用户ID

2.2 文件名生成

String originalFilename = file.getOriginalFilename();
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName = UUID.randomUUID().toString().replace("-", "") + fileExtension;
  • 获取原始文件名
  • 提取文件扩展名(如.jpg, .png)
  • 使用UUID生成唯一文件名,避免重名冲突

2.3 文件上传

String avatarUrl = LocalUploadImageUtils.uploadFile(file, fileName);

调用你之前定义的LocalUploadImageUtils工具类完成:

  1. 构建本地存储路径:ConfigFileMessageUtils.IMAGE_ALL_DIR + fileName
  2. 确保目录存在
  3. 使用transferTo()保存文件
  4. 返回可访问的URL

2.4 数据库更新

MyUser user = myUserService.selectMyUserByUserId(userId);
user.setAvatarUrl(avatarUrl);
myUserService.updateMyUser(user);
  1. 根据用户ID查询用户
  2. 更新头像URL字段
  3. 保存到数据库

2.5 结果返回

return new ApiResult<>(1, "头像上传成功", avatarUrl);

返回统一格式的响应,包含:

  • 状态码(1成功/0失败)
  • 消息
  • 数据(这里是头像URL)

3. 完整技术栈协作

前端(表单提交)↓ (HTTP POST /uploadAvatar)
Spring MVC Controller↓ (MultipartFile)
LocalUploadImageUtils (文件存储)↓ (返回URL)
MyUserService (数据库更新)↓ 
返回ApiResult给前端

4. 关键设计考虑

  1. 唯一文件名:使用UUID避免重名覆盖
  2. URL生成:工具类自动构建完整访问URL
  3. 事务完整性:先确保文件保存成功,再更新数据库
  4. 错误处理:try-catch捕获可能异常,返回友好错误信息

5. 潜在优化点

  1. 文件验证:添加对文件类型、大小的检查
  2. 图片处理:可集成缩略图生成
  3. 异步处理:大文件上传可改为异步方式
  4. 分布式存储:未来可扩展为云存储方案
  5. 安全控制:添加权限验证,防止越权修改

这个实现是一个典型而完整的Spring Boot文件上传应用场景,涵盖了从文件接收到存储再到数据库更新的完整流程,具有良好的可扩展性和实用性。

http://www.xdnf.cn/news/345205.html

相关文章:

  • CFCA受邀参加盛京银行手机银行7.0发布会
  • Kibana vs Grafana:日志分析能力深度对比与移动应用案例
  • 企业面试题综合(1)
  • SLAM文献之KernelGPA: A Globally Optimal Solution to Deformable SLAM in Closed-form
  • Kafka消息不丢失处理
  • MATLAB界面——valueChangedFcn回调和valueChanging回调
  • 数值分析——条件数
  • 04-redis
  • 从零开始了解数据采集(二十四)——工业4.0讲解
  • 企业微信自建消息推送应用
  • 【JS逆向基础】爬虫核心模块:request模块与包的概念
  • MySQL创新应用:分布式数据库与AI融合的智能分析平台
  • 问鼎昇腾AI创新大赛金奖!aiXcoder如何重塑软件开发新范式?
  • 为什么强调 RESTful 的无状态性?-优雅草卓伊凡
  • Python实例题:Python获取喜马拉雅音频
  • 【AI入门】CherryStudio入门5:创建知识库,对接Obsidian 笔记
  • C++ 深入解析 数据结构中的 AVL树的插入 涉及的旋转规则
  • 手撕基于AMQP协议的简易消息队列-2(所用第三方库的介绍与简单使用)
  • C++:扫雷游戏
  • 解决正点原子IMX6U开发板Buildroot构建qt根文件系统解压后,没有库文件
  • MySQL数据库初级体验
  • 2025年道路运输安全员考试题库及答案
  • 物流无人机自动化装卸技术解析!
  • Python开发系统
  • 网络接入服务商查询
  • 解决:‘java‘ 不是内部或外部命令,也不是可运行的程序-Java环境变量配置(含JDK8、JDK21安装包一站式配置)
  • 手写Promise的静态方法
  • Memgraph 的安装教程
  • 从一城一云到AI CITY,智慧城市进入新阶段
  • Oracle数据库DBF文件收缩