博主介绍:全网粉丝10W+,CSDN博客专家、全栈领域优质创作者,3年JAVA全栈开发经验,专注JAVA技术、系统定制、远程指导,致力于企业数字化转型。
研究方向:SpringBoot、Vue.JS、MyBatisPlus、Redis、SpringSecurity、MySQL、小程序、Android、Uniapp等。


视频版教程:


一、找到原因

1.1 启动项目

首先,博主以 T103 项目为例,启动项目,后端截图如下。

在这里插入图片描述

在这里插入图片描述

接着,浏览器输入

http://localhost:8081/#/login

即可进入系统,如下图所示。

在这里插入图片描述

我们使用账号 admin,密码 123456 进入系统,如下图所示。

在这里插入图片描述

1.2 复刻问题

我们点击左侧的用户管理菜单,点击第一行数据的编辑按钮,如下图所示。

在这里插入图片描述

然后我们删除现有的图片,上传一张新的图片,如下图所示。

在这里插入图片描述

我们发现,前端发起了一个上传文件的接口: http://localhost:8081/springboot07j52/file/upload

在这里插入图片描述

接口返回了文件名称:1741959091899.png

此时,我们可以在idea的target目录 找到这个文件。

在这里插入图片描述

在编辑界面点击保存之后,我们依然可以在主界面看到这张图片,如下图所示。

在这里插入图片描述

图片以URL的形式,存储在数据库。

在这里插入图片描述

但如果删除了target文件夹,重新编译之后,这个图片文件就不存在了。

在这里插入图片描述

模块界面上,图片也就无法展示,如下图所示。

在这里插入图片描述


二、解决问题 后端部分

在第一章的学习中,已经找到T系列项目图片上传失败的问题,也就是存储文件路径不正确的问题。

也就是说,应该存储在稳定的目录,而不是临时的target目录。

2.1 引入依赖

由于新加入的 MockMultipartFile 类需要引入 spring-test 依赖,所以需要在 pom.xml 文件里面加入如下代码。

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
</dependency>

在这里插入图片描述

2.2 复制文件到源码目录

首先,找到后端代码的 com.controller.FileController.java 文件的 upload 方法,现有代码如下。

@RequestMapping("/upload")
public R upload(@RequestParam("file") MultipartFile file,String type) throws Exception {
	if (file.isEmpty()) {
		throw new EIException("上传文件不能为空");
	}
	String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
	File path = new File(ResourceUtils.getURL("classpath:static").getPath());
	if(!path.exists()) {
		path = new File("");
	}
	File upload = new File(path.getAbsolutePath(),"/upload/");
	if(!upload.exists()) {
		upload.mkdirs();
	}
	String fileName = new Date().getTime()+"."+fileExt;
	File dest = new File(upload.getAbsolutePath()+"/"+fileName);
	file.transferTo(dest);
	if(StringUtils.isNotBlank(type) && type.equals("1")) {
		ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
		if(configEntity==null) {
			configEntity = new ConfigEntity();
			configEntity.setName("faceFile");
			configEntity.setValue(fileName);
		} else {
			configEntity.setValue(fileName);
		}
		configService.insertOrUpdate(configEntity);
	}
	return R.ok().put("file", fileName);
}

然后我们新增 copyMultipartFile 方法,这个方法用于复制一个新的 MultipartFile 对象。

MultipartFile 类是引用对象,同学们不能使用 MultipartFile newFile = originalFile; 的方式去赋值。

public MultipartFile copyMultipartFile(MultipartFile originalFile) {
	try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
		// 将原始文件内容复制到输出流
		FileCopyUtils.copy(originalFile.getInputStream(), outputStream);
		// 将输出流转换为输入流,以便创建新的 MultipartFile
		ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
		// 使用新的输入流创建新的 MultipartFile 对象(这里以MockMultipartFile为例)
		return new MockMultipartFile(originalFile.getName(), originalFile.getOriginalFilename(),
				originalFile.getContentType(), inputStream);
	} catch (IOException e) {
		throw new RuntimeException("Failed to copy MultipartFile", e);
	}
}

其中类引用的代码如下。


import java.io.*;
import org.apache.commons.io.FileUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.FileCopyUtils;

然后我们使用如下代码复制一份新的文件类。

// 复制一份新的文件
MultipartFile newFile = copyMultipartFile(file);

在这里插入图片描述

然后即可将前端上传的文件,复制到源码目录,代码如下。

File dest2 = new File("C:\\code\\test\\t\\back\\src\\main\\resources\\static\\upload\\"+fileName);
newFile.transferTo(dest2);

其中 "C:\\code\\test\\t\\back\\src\\main\\resources\\static\\upload\\" 为博主后端项目的绝对路径,同学们需要根据自己的实际目录进行替换。

在这里插入图片描述

2.3 问题解决

代码修改完成后,重启项目后端,新上传的图片即可正常显示,适用于上传图片的实时预览,和重启后端项目之后的文件预览。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐