SpringBoot+Vue+ElementUI实现头像上传

深碍√TFBOYSˉ_ 2024-04-03 11:52 191阅读 0赞

SpringBoot+Vue+ElementUI实现头像上传

  • 1.基础知识(补充)
  • 2.后端依赖导入Maven
  • 3.后端Controller代码(核心)
  • 4.配置代码(核心)
  • 5.前端代码
  • 6.总结

1.基础知识(补充)

File协议:

FIle协议也叫本地文件传输协议 ,主要用于访问本地计算机中的文件,就如同在Windows资源管理器中打开文件或者通过右键单击‘打开’一样。即File协议是访问你本机的文件资源。
要使用File协议,基本的格式如下:file:///文件路径。

2.后端依赖导入Maven

这里使用到了hutool工具,很好用,不过建议新手多了解底层,在使用工具

  1. <!-- 文件上传工具类 -->
  2. <dependency>
  3. <groupId>commons-fileupload</groupId>
  4. <artifactId>commons-fileupload</artifactId>
  5. <version>1.4</version>
  6. </dependency>
  7. <!-- hutool 工具类 -->
  8. <dependency>
  9. <groupId>cn.hutool</groupId>
  10. <artifactId>hutool-all</artifactId>
  11. <version>5.8.8</version>
  12. </dependency>

3.后端Controller代码(核心)

看不懂代码请认真看代码上面的注释,写的比较详细了,如果有什么不懂的,或者有什么问题,可以在评论区指出,都会回答的!!!为的就是共同学习!!!

这个项目我用到的是SpringSecurity,然后通过一个BaseController封装了SecurityContextHolder来获取当前登录用户的信息,其次就是用到了一些定义好的变量

将上传的文件通过前端表单传给后端,后端通过file.transferTo()方法下载到本地

  1. @PostMapping("/avatar")
  2. public R<Map<String,Object>> avatar(MultipartFile file) throws IOException {
  3. // 获取当前登录用户
  4. LoginUser loginUser = getLoginUser();
  5. // 文件名称 时间日期+文件名_uuid+后缀
  6. String fileName = StrUtil.format("{}/{}_{}.{}", DateUtil.format(DateUtil.date(),"yyy/MM/dd"), FilenameUtils.getBaseName(file.getOriginalFilename()),DateUtil.format(new Date(),"yyyyMMdd")+ IdUtil.fastUUID(),FilenameUtils.getExtension(file.getOriginalFilename()));
  7. // 父目录
  8. String baseDir = WenJianConfig.getAvatarPath();
  9. //路径拼接
  10. File desc = new File(baseDir + File.separator + fileName);
  11. if (!desc.exists())
  12. {
  13. if (!desc.getParentFile().exists())
  14. {
  15. desc.getParentFile().mkdirs();
  16. }
  17. }
  18. // 下载
  19. file.transferTo(desc);
  20. int dirLastIndex = WenJianConfig.getProfile().length() + 1;
  21. // 截取upload/下的名称存入数据库
  22. String currentDir = baseDir.substring(dirLastIndex);
  23. // /profile/avatar/2022/10/10/293a05e068a7dfb298c87238de858130_2022101031242e4a-079a-4d4b-9c5c-139f5d2152ab.jpeg
  24. // Constants.RESOURCE_PREFIX = "/profile";
  25. String avatar = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
  26. // 修改数据库中的头像路径
  27. iSysUserService.updateUserAvatar(loginUser.getUser().getUsername(),avatar);
  28. Map<String, Object> map = new HashMap<>();
  29. // 将头像路径返回,这里是为了头像上传后有一个回显的效果
  30. map.put("imgUrl",avatar);
  31. // 将缓存中的对象信息进行一个更新
  32. loginUser.getUser().setAvatar(avatar);
  33. tokenUtil.setLoginUser(loginUser);
  34. return R.ok(map);
  35. }

4.配置代码(核心)

在application.yml中配置本地保存的路径,后面想改下载的路径可以直接在配置文件中修改

  1. # 项目相关配置
  2. wenjian:
  3. # 文件路径 示例( Windows配置D:/wenjian/uploadPath,Linux配置 /home/wenjian/uploadPath)
  4. profile: D:/wenjian/uploadPath

获取yml中配置路径的属性值

  1. package com.sky.common.config;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.stereotype.Component;
  5. /**
  6. * @author 尹稳健~
  7. * @version 1.0
  8. * @time 2022/10/9
  9. */
  10. @Component
  11. @ConfigurationProperties(prefix = "wenjian")
  12. public class WenJianConfig {
  13. /** 上传路径 */
  14. private static String profile;
  15. public static String getProfile() {
  16. return profile;
  17. }
  18. public void setProfile(String profile) {
  19. WenJianConfig.profile = profile;
  20. }
  21. /**
  22. * 获取导入上传路径
  23. */
  24. public static String getImportPath()
  25. {
  26. return getProfile() + "/import";
  27. }
  28. /**
  29. * 获取头像上传路径
  30. */
  31. public static String getAvatarPath()
  32. {
  33. return getProfile() + "/avatar";
  34. }
  35. /**
  36. * 获取下载路径
  37. */
  38. public static String getDownloadPath()
  39. {
  40. return getProfile() + "/download/";
  41. }
  42. /**
  43. * 获取上传路径
  44. */
  45. public static String getUploadPath(){
  46. return getProfile() + "/upload";
  47. }
  48. }

这个时候就有人会问如何进行一个头像回显?
就拿这个路径进行举例:

  1. /profile/avatar/2022/10/10/293a05e068a7dfb298c87238de858130_2022101031242e4a-079a-4d4b-9c5c-139f5d2152ab.jpeg

凭什么网页拿着这玩意可以直接展示出来一张图片?
因为在后端这里进行一个路径映射

  1. @Configuration
  2. public class MyWebConfigurer implements WebMvcConfigurer {
  3. @Override
  4. public void addResourceHandlers(ResourceHandlerRegistry registry) {
  5. /** 本地文件上传路径 */
  6. // Constants.RESOURCE_PREFIX = "/profile"
  7. // WenJianConfig.getProfile() = 你本地存储的位置
  8. registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
  9. .addResourceLocations("file:" + WenJianConfig.getProfile() + "/");
  10. }
  11. }

图片展示在网页上
在这里插入图片描述

5.前端代码

前端使用的是Vue+ElementUI,所以我只截图关键代码,谢谢!!

参数解读:

  • action:是必须指定的,这对应着你后端的接口。
  • headers:我这里为什么指定了呢?一开始我是没有指定,但是我发现如果你不指定,那么你通过点击确定按钮后,后端不会进行一个响应,因为SpringSecurity把他拦截下来了,因为你本次请求没有携带token信息,所以这里我添加了一个headers。
  • on-success:这个也是关键参数,文件上传成功时的钩子,将上传的文件流传给后端进行接收,后端再将数据进行响应回前端 。

    <el-upload

    1. class="avatar-uploader"
    2. action="http://localhost:8080/manage/sys/user/avatar"
    3. :show-file-list="false"
    4. :on-success="handleAvatarSuccess"
    5. :before-upload="beforeAvatarUpload"
    6. :headers="headerObj"
    7. >
    8. <img v-if="avatar" :src="avatar" class="img-circle img-lg" />
    9. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    10. </el-upload>
  1. <script>
  2. export default {
  3. methods: {
  4. handleAvatarSuccess(res, file) {
  5. let formData = new FormData();
  6. // 将文件传给后端下载
  7. formData.append("file", file);
  8. this.$message.success(res.msg);
  9. this.avatar = "http://localhost:8080" + res.data.imgUrl;
  10. // 将数据保存再vuex中
  11. this.$store.commit("setAvatar", this.avatar);
  12. },
  13. beforeAvatarUpload(file) {
  14. const isJPG = file.type === "image/jpeg";
  15. const isLt2M = file.size / 1024 / 1024 < 2;
  16. if (!isJPG) {
  17. this.$message.error("上传头像图片只能是 JPG 格式!");
  18. }
  19. if (!isLt2M) {
  20. this.$message.error("上传头像图片大小不能超过 2MB!");
  21. }
  22. return isJPG && isLt2M;
  23. },
  24. },
  25. }
  26. </script>

6.总结

  1. 文件上传不难,关键点在前端接收文件,然后将文件传给后端,后端将文件通过流的方式下载到指定的位置。
  2. 稍微难一点的地方就是图片回显,只需要将本地的路径返回给前端就行通过file:/文件路径,的方式进行一个图片的回显

发表评论

表情:
评论列表 (有 0 条评论,191人围观)

还没有评论,来说两句吧...

相关阅读