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

头像上传功能的实现

第一步:确保数据库和对应的实体类中存在avatar字段

第二步:配置中添加文件信息

file.upload.path=D:/Project/uploads 
spring.servlet.multipart.max-file-size=2MB
spring.servlet.multipart.max-request-size=10MB

从上到下分别是:文件上传后存储的位置、上传文件的最大大小、上传文件的最大大小。

第三步:配置WebConfig

    @Value("${file.upload.path}")private String uploadDir;@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/uploads/**").addResourceLocations("file:" + uploadDir + "/");}

 代码解释:

    @Value("${file.upload.path}")private String uploadDir;
  • @Value("${file.upload.path}"):这是Spring的一个注解,用于将配置文件(如application.propertiesapplication.yml)中的file.upload.path属性值注入到uploadDir这个变量中。这个属性值通常是你希望存储文件上传结果的本地文件系统的路径。

  • addResourceHandlers 方法:这是一个在Spring MVC中配置静态资源处理的方法。通过调用registry.addResourceHandler("/uploads/**"),你定义了一个URL模式(在这个例子中是/uploads/开头的所有路径),当浏览器请求该模式下的资源时,Spring会尝试从对应的资源位置提供文件。

  • addResourceLocations("file:" + uploadDir + "/"):这行代码指定了资源处理器从哪里获取文件。file: 前缀告诉Spring从文件系统中读取数据,而不是从类路径中。这里使用了之前通过@Value注入的uploadDir,这意味着所有/uploads/路径下的请求会被映射到这个目录,从而允许浏览器访问存储在该目录下的文件。

第四步:实现FileService

public interface FileService {String uploadFile(MultipartFile file) throws IOException;
}

第五步:实现FileServiceImpl

@Service
public class FileServiceImpl implements FileService {@Value("${file.upload.path}")private String uploadDir;@Overridepublic String uploadFile(MultipartFile file) throws IOException {//1. 判断文件是否为空if (file.isEmpty()) {return "文件为空";}//2. 判断文件类型,仅支持JPG、JPEG、PNG格式的图片//3.生成唯一文件名,防止文件充满导致覆盖String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();System.out.println("fileName: " + fileName);Path filePath = Paths.get(uploadDir, fileName);System.out.println("filePath: " + filePath);//4. 保存文件Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);//5. 返回相对路径,用于前端显示return "/uploads/" + fileName;}
}

第六步:实现FileController

@RestController
@RequestMapping("/api/file")
public class FileController {@Autowiredprivate FileService fileService;@PostMapping("/avatar")public JsonResult uploadAvatar(@RequestParam("file") MultipartFile file) throws IOException {String path = fileService.uploadFile(file);return JsonResult.success(path);}
}

第七步:前端代码实现

1. 准备工作

在登录方法中,设置 localStorage.setItem 方法,将用户登录成功后返回的数据以字符串的形式存储在浏览器的本地缓存中,用于后续页面的使用,例如:登录成功后使用get方法获取头像和用户名用于页面展示。

let user = JSON.parse(localStorage.getItem("code_user") || '{}');
const username = ref(user.name)
const avatarUrl = ref(`http://localhost:8080${user.avatar}`);
const handleLogin = () => {loginFormRef.value.validate((valid) => {if (valid) {request.post('/api/user/login', loginForm).then(res => {if (res.code === '200') {//将用户登录成功后返回的数据以字符串的形式存储在浏览器的本地存储中,供后续页面使用(如自动登录)localStorage.setItem("code_user", JSON.stringify(res.data || {}))//添加调试console.log("存储的用户数据为:", JSON.parse(localStorage.code_user))setTimeout(() => {ElMessage.success('登录成功')router.push('/home/chat')}, 50)}}).catch(error => {if (error.code === 400) {ElMessage.error(error.message || '用户不存在' || '密码错误');} else {ElMessage.error(`登录失败:${error.message}`);}})}})
}

2. template部分

          <el-form-item label="头像" prop="avatar"><el-uploadaction="http://localhost:8080/api/file/avatar":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload":data="{userId:user.id}"name="file"class="avatar-uploader"><el-avatar :size="100" :src="avatarUrl"/><template #tip><div class="el-upload__tip">点击头像上传新照片(支持JPG/JPEG/PNG,≤2MB)</div></template></el-upload></el-form-item>

3. script部分

/*定义avatarUrl变量*/
const avatarUrl = ref(`http://localhost:8080${user.avatar}`);/*上传前预处理:图片类型只能是JPG/JPEG/PNG,大小不能超过2MB*/
const beforeAvatarUpload = (rawFile) => {const allowedTypes = ['image/jpeg', 'image/png', 'image/jpg'];const isImage = allowedTypes.includes(rawFile.type);const isLt2M = rawFile.size / 1024 / 1024 < 2;if (!isImage) {ElMessage.error('头像只能是 JPG/JPEG/PNG 格式!');}if (!isLt2M) {ElMessage.error('头像大小不能超过 2MB!');}return isImage && isLt2M;
}/*上传成功处理*/
const handleAvatarSuccess = (response) => {if (response.code === 200 || response.code === "200") {userInfo.value.avatar = response.data;avatarUrl.value = `http://localhost:8080${response.data}?t=${Date.now()}`;//更新本地缓存中的用户头像URL,防止刷新页面后出现旧头像的展现const updatedUser = {...user, avatar: response.data};localStorage.setItem("code_user", JSON.stringify(updatedUser));ElMessage.success('头像上传成功!');console.log("avatarUrl.value:" + avatarUrl.value)console.log("头像路径:" + response.data);// 更新数据库中的用户头像URL,也就是更新数据库中的avatar字段值request.post(`/api/user/updateUser`, userInfo.value).then(res => {if (res.code === 200 || res.code === "200") {console.log("头像信息已保存")} else {ElMessage.error('头像保存失败!');}}).catch(error => {console.error("保存头像失败:", error);ElMessage.error('保存头像失败!');});} else {ElMessage.error('头像上传失败!');}
}

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

相关文章:

  • 51单片机基础部分——矩阵按键检测
  • Python爬虫实战:研究Hyper 相关技术
  • 内存泄漏检测工具-学习(一)
  • pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
  • 【51单片机】2. 进阶点灯大师
  • 【论文阅读笔记】《A survey on deep learning approaches for text-to-SQL》
  • The dependencies of some of the beans in the application context form a cycle
  • 设计模式-建造者模式
  • 使用Python调整MP3音频文件的响度和音量
  • (每日一道算法题)二叉树剪枝
  • STM32开发,创建线程栈空间大小判断
  • Anaconda
  • 【Java学习笔记】String类总结
  • wifi | 软件: Synaptics _Linux 系统平台蓝牙hciconfig操控指令详述
  • 网易邮箱启用POP3/SMTP/IMAP服务
  • C++ 中的参数传递
  • day26-计算机网络-4
  • 动端React表格组件:支持合并
  • SpringAI Alibaba实战文生图
  • 基于autodl的imageBind部署
  • 6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
  • VSCode CUDA C++进行Linux远程开发
  • 行为设计模式之Command (命令)
  • 力扣HOT100之二分查找:153. 寻找旋转排序数组中的最小值
  • 管道与进程间通信
  • Riverpod与GetX的优缺点对比
  • KTO: Model Alignment as Prospect Theoretic Optimization
  • 【基础算法】差分算法详解
  • 机器学习的数学基础:神经网络
  • Ajax Systems公司的核心产品有哪些?