React传FormData到Spring Boot后端FTP存储文件覆盖问题如何解决
React+Spring Boot FTP文件上传覆盖问题解决方案
一、修改ipData后后端未收到新文件排查
按照前后端分别排查:
- 前端侧
- 每次发起上传请求前必须重新实例化
FormData对象,不要全局复用同一个实例。如果复用实例,需要先调用formData.delete('file')删除旧的文件字段,再append新生成的Blob,避免旧文件残留。 - 生成Blob的逻辑必须放在请求触发的回调函数内,不要在组件挂载时只执行一次,否则ipData更新后生成的仍是旧内容的Blob。
- 可通过浏览器控制台「网络」面板,查看上传请求的Payload内的文件大小,确认和修改后ipData生成的Blob大小一致,排除前端传参异常。
- 每次发起上传请求前必须重新实例化
- 后端侧
- 接收到
MultipartFile参数后,先打印文件大小、输入流长度,确认是否收到了前端传递的新文件:如果收到的文件大小和旧文件一致,问题出在前端传参环节;否则问题出在后端FTP存储逻辑。
- 接收到
二、存储多个文件不覆盖旧文件实现方案
核心逻辑是保证FTP服务器上存储的文件名唯一,不要使用固定文件名,推荐两种落地方式:
方案1:文件名加唯一标识后缀
在原始文件名基础上拼接时间戳+随机数,确保每次上传的文件名都不重复,Java代码示例:
import org.apache.commons.lang3.RandomStringUtils; import java.util.UUID; // 1. 取原始文件名,如果你上传的是固定后缀的json文件,也可以直接自定义前缀 String originalFilename = file.getOriginalFilename(); int suffixIndex = originalFilename.lastIndexOf("."); String prefix = originalFilename.substring(0, suffixIndex); String suffix = originalFilename.substring(suffixIndex); // 2. 生成唯一文件名,两种方式选其一即可 // 方式A:时间戳+6位随机数 String uniqueFileName = String.format("%s_%d_%s%s", prefix, System.currentTimeMillis(), RandomStringUtils.randomNumeric(6), suffix); // 方式B:UUID拼接 String uniqueFileName = String.format("%s_%s%s", prefix, UUID.randomUUID().toString().replace("-",""), suffix); // 3. 用唯一文件名调用FTP存储 boolean storeResult = ftpClient.storeFile(uniqueFileName, file.getInputStream()); // 注意要判断存储结果,捕获异常,避免静默失败
方案2:按日期分目录存储
适合文件量较大的场景,按上传日期生成子目录,同目录下再用唯一文件名存储,代码示例:
import java.text.SimpleDateFormat; import java.util.Date; // 1. 生成日期目录名,格式可自定义 String dateDir = new SimpleDateFormat("yyyyMMdd").format(new Date()); // 2. 检查FTP目录是否存在,不存在则创建 if (!ftpClient.changeWorkingDirectory(dateDir)) { ftpClient.makeDirectory(dateDir); ftpClient.changeWorkingDirectory(dateDir); } // 3. 再执行上述的文件存储逻辑即可
额外注意事项
- 每次调用
storeFile后要判断返回值是否为true,确认文件上传成功,同时要在finally块中关闭输入流、调用ftpClient.completePendingCommand(),避免资源泄漏和后续FTP操作卡住。 - 如果需要关联文件和对应ipData的内容,可以在数据库中存储原始文件名、唯一存储文件名、上传时间、ipData关联标识等信息,方便后续查找。
内容的提问来源于stack exchange,提问作者Janitha_Missaka
相关产品推荐
相关产品推荐

