无缝集成:使用Spring Boot和Vue实现头像上传与回显功能

🌟 前言

欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍

  • 🤖 洛可可白:个人主页

  • 🔥 个人专栏:✅前端技术 ✅后端技术

  • 🏠 个人博客:洛可可白博客

  • 🐱 代码获取:bestwishes0203

  • 📷 封面壁纸:洛可可白wallpaper

在这里插入图片描述

文章目录

无缝集成:使用Spring Boot和Vue实现头像上传与回显功能

在现代Web应用中,用户个性化体验尤为重要,其中头像上传与回显是一个常见的功能需求。本文将详细介绍如何使用Spring Boot和Vue.js构建一个前后端协同工作的头像上传系统,并实现图片的即时回显。

技术栈介绍

  • Spring Boot:一个基于Spring框架的开源项目,用于简化Spring应用的初始搭建以及开发过程。它通过提供默认配置减少开发中的配置工作,使得开发者能够快速启动和部署Spring应用。

  • Vue.js:一个渐进式JavaScript框架,用于构建用户界面。Vue的核心库只关注视图层,易于上手,同时也能够配合其他库或现有项目使用。Vue.js以其轻量级、高效性和灵活性而广受欢迎。

后端实现

后端使用Spring Boot框架,通过@RestController注解定义一个控制器UploadController,提供/upload端点处理文件上传请求。代码中使用了MultipartFile来接收上传的文件,并将其保存到服务器的指定目录。

添加依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

代码注释

@RestController
public class UploadController {@Operation(summary = "上传图片到本地")@PostMapping("/upload")public String upload(MultipartFile file) {if (file.isEmpty()) {return "图片为空";}String originalFilename = file.getOriginalFilename();String fileNamePrefix = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());assert originalFilename != null;String fileNameSuffix = "." + originalFilename.split("\\.")[1];String fileName = fileNamePrefix + fileNameSuffix;ApplicationHome applicationHome = new ApplicationHome(this.getClass());//String pre = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() + "\\src\\main\\resources\\static\\images\\";String pre = applicationHome.getDir().getParentFile().getParentFile().getParentFile().getAbsolutePath() + "\\spring-ui\\src\\assets\\avatar\\";String path = pre + fileName;try {file.transferTo(new File(path));String replace = path.replace(applicationHome.getDir().getParentFile().getParentFile().getParentFile().getAbsolutePath() + "\\spring-ui\\src", "/src");return replace.replace("\\", "/");} catch (IOException e) {e.printStackTrace();}return "图片上传失败";}
}

前端实现

前端使用Vue.js框架,通过封装axios请求和全局配置,实现与后端的通信。同时,使用Vite作为构建工具,配置代理解决跨域问题。

代码注释

全局配置封装
// config/index.ts
export const baseURL = '/api'; // 基础URL
export const timeout = 10000; // 请求超时时间
export const headers = { 'X-Custom-Header': 'foobar' }; // 自定义请求头
Axios二次封装
// request/index.ts
const request = axios.create({// 配置axios实例baseURL,timeout,headers
});
// 添加请求和响应拦截器
request.interceptors.request.use((config) => {// 请求拦截器逻辑return config;
}, (error) => {// 响应拦截器逻辑return Promise.reject(error);
});
Api接口请求
//api/index.ts
import * as common from '@/api/common'
import * as user from '@/api/user'const api = {common,user,
}export default api;
//api/common.ts
import request from "@/request";// 响应接口
export interface UploadRes {}/*** 上传图片到本地* @param {string} file* @returns*/
export function upload(file: object): Promise<UploadRes> {return request.post(`/upload`, file);
}
//api/user.ts
import request from "@/request";// 参数接口
export interface UpdateUserParams {id?: number;name?: string;sex?: string;age?: number;pic?: string;acc?: string;pwd?: string;phone?: string;email?: string;dept?: string;post?: string;status?: string;createBy?: string;createTime?: string | unknown;updateBy?: string;updateTime?: string | unknown;remark?: string;
}// 响应接口
export interface UpdateUserRes {message: string;success: boolean;code: number;data: Record<string, unknown>;
}/*** 修改-账号* @param {object} params $!{table.comment}* @param {number} params.id* @param {string} params.name 姓名* @param {string} params.sex 性别* @param {number} params.age 年龄* @param {string} params.pic 头像* @param {string} params.acc 账号* @param {string} params.pwd 密码* @param {string} params.phone 电话号码* @param {string} params.email 电子邮件* @param {string} params.dept 用户部门* @param {string} params.post 用户岗位* @param {string} params.status 状态(0正常 1停用)* @param {string} params.createBy 创建者* @param {object} params.createTime 创建时间* @param {string} params.updateBy 更新者* @param {object} params.updateTime 更新时间* @param {string} params.remark 备注* @returns*/
export function updateUser(params: UpdateUserParams): Promise<UpdateUserRes> {return request.post(`/userEntity/update`, params);
}

解决CORS跨域问题
// vite.config.ts
export default defineConfig({server: {proxy: {"/api": {target: "http://localhost:9090/", // 后端服务地址changeOrigin: true, // 是否改变源rewrite: (path) => path.replace(/\/api/, ""), // 重写路径},},},
});
业务处理代码
<template><!-- 上传组件和提示信息 --><el-upload drag :show-file-list="false" :limit="1" action="#" :auto-upload="false" accept=".png":on-change="handleChanges"><el-icon class="el-icon--upload"><upload-filled/></el-icon><div class="el-upload__text"><em> 点击 </em><em> 拖动文件 </em>上传</div><template #tip><div class="el-upload__tip">仅支持 jpg/png 格式文件大小小于 2MB</div></template></el-upload>
</template><script setup>
import { ref } from "vue";
import api from "@/api";// 响应式引用,用于存储用户信息
const user = ref({});// 生命周期钩子,初始化时获取用户信息
onMounted(() => {user.value = JSON.parse(localStorage.getItem("user"));
});// 处理文件变化,上传文件并更新用户信息//修改头像
const handleChanges = (file) => {if (file.raw.type !== 'image/png') {//限制文件类型ElMessage.error({message: "只能上传png格式的文件", grouping: true, showClose: true});return false;}if (file.raw.size / 1024 / 1024 > 5) {ElMessage.error('文件大于 5MB!')return false;}const param = new FormData();param.append('file', file.raw);api.common.upload(param).then((res: any) => {if (res !== null) ElMessage.success("上传成功");if (res === null) ElMessage.error("上传失败");api.user.updateUser({id: user.value.id, pic: res}).then((res: any) => {api.user.selectUserByAcc(user.value.acc).then((res: any) => {//更新缓存localStorage.setItem("user", JSON.stringify(res.data));//更新左侧描述列表user.value = res.data;})})})
};
</script><style scoped>
:deep(.el-descriptions__label) {min-width: 60px !important;
}
</style>

功能演示

在文章的最后,我们将展示上传头像功能的完整流程,包括前端的上传界面、后端的文件保存逻辑,以及成功上传后的头像回显效果。

上传前

上传后

结语

通过本文的介绍,我们学习了如何使用Spring Boot和Vue.js实现一个完整的头像上传与回显功能。这种前后端分离的开发模式不仅提高了开发效率,也使得系统更加模块化和易于维护。随着技术的不断进步,我们期待未来能够有更多类似的协同工作解决方案出现,以满足不同场景下的开发需求。

如果对你有帮助,点赞👍、收藏💖、关注🔔是我更新的动力!👋🌟🚀

🎉 往期精彩回顾

前端与后端协同:实现Excel导入导出功能
Java日期格式化:掌握时间的艺术
JavaScript日期格式化:从原始值到用户友好的字符串
入门教程:Windows搭建C语言和EasyX开发环境
CentOS系统下Docker的安装教程
Spring Boot单元测试全指南:使用Mockito和AssertJ
Yarn简介及Windows安装与使用指南
H5实现3D旋转照片墙教程
Element-Plus 实现动态渲染图标教程
MyBatis-Plus分页接口实现教程:Spring Boot中如何编写分页查询
Element-Plus下拉菜单边框去除教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/807917.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查询category的id存在于项目表中category_id_list的json array字段中

表category 表project 查询category的id存在于项目表中category_id_list的json array字段中。

Cmake学习笔记3

视频学习地址08-重命名和安装共享库_哔哩哔哩_bilibili 1、同时创建动态连接和静态连接库 SET_TARGET_PROPERTIES 这条指令可以用来设置输出的名称&#xff0c;对于动态库&#xff0c;还可以用来指定动态库版本和API版本 SET(LIBHELLO_SRC hello.cpp)ADD_LIBRARY(hello_sta…

4.11Qt

完善网络聊天室客户端实现 工程文件 QT core gui network 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpSocket> #include<QMessageBox>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEcl…

前端三剑客 —— JavaScript (第九节)

目录 内容回顾&#xff1a; 1.事件解除 2. Ajax jQuery选择器 回顾CSS选择器 CSS选择 1.基本选择器 2.包含选择器 3.伪类选择器 4.伪元素选择器 5.属性选择器 jQuery 库 jQuery 动画 系统动画 自定义动画 常见API操作 内容回顾&#xff1a; 1.事件解除 如果是使…

头歌-机器学习 第9次实验 随机森林

第1关&#xff1a;Bagging 任务描述 本关任务&#xff1a;补充 python 代码&#xff0c;完成 BaggingClassifier 类中的 fit 和 predict 函数。请不要修改 Begin-End 段之外的代码。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 什么是 Bagging&#xf…

李廉洋;4.11#黄金,WTI原油#行情走势分析策略。

美国银行预计&#xff0c;在今天召开的欧洲央行会议上不会有重大的政策变化&#xff0c;但欧洲央行正逐渐接近开始降息&#xff0c;尽管它采取的是一种谨慎的、依赖数据的方式。虽然欧洲央行对降息轨迹的信心不断增强&#xff0c;但降息的具体速度和幅度仍未公布&#xff0c;而…

QT系列教程(2) 创建项目和编译

新建Qt Widgets应用 我们启动qt creator 创建项目&#xff0c;选择Qt Widgets应用 接下来选择项目目录&#xff0c;项目名字就叫helloworld 构建系统选择qmake 我们创建一个名字为HelloDialog的类&#xff0c;继承于QDialog 构建套件选择你们安装的就行了&#xff0c;我这里选…

【LeetCode刷题记录】560. 和为 K 的子数组

560 和为 K 的子数组 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2 示例 2&#xff1a; 输入&#xf…

负载均衡原理和负载均衡算法代码案例

由于在这个文本环境中无法直接绘制图形&#xff0c;我将尽量使用文字描述来详细解释负载均衡原理和算法&#xff0c;并提供一个简单的代码案例。但请注意&#xff0c;真正理解负载均衡和算法的工作最好通过查看图形化表示和可视化工具。 负载均衡原理 负载均衡是通过在网络架…

【leetcode面试经典150题】22. Z 字形变换(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

ELK及ELFK排错

目录 一、ELK及ELFK排错思路 1.1filebeat侧排查 1.2logstash侧排查 1.3ES、kibana侧问题 一、ELK及ELFK排错思路 1.1filebeat侧排查 第一步&#xff1a;排查filebeat上的配置文件有没有写错&#xff0c;filebeat的配置文件是yml文件&#xff0c;一定要注意格式。 第二步…

Day3-struct类型、列转行、行转列、函数

Hive 数据类型 struct类型 struct&#xff1a;结构体&#xff0c;对应了Java中的对象&#xff0c;实际上是将数据以json形式来进行存储和处理 案例 原始数据 a tom,19,male amy,18,female b bob,18,male john,18,male c lucy,19,female lily,19,female d henry,18,male davi…

python botos s3 aws

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html AWS是亚马逊的云服务&#xff0c;其提供了非常丰富的套件&#xff0c;以及支持多种语言的SDK/API。本文针对其S3云储存服务的Python SDK&#xff08;boto3&#xff09;的使用进行介绍。 …

男生裤子怎么选?5条永远不会出错的长裤分享

作为一名热衷于分享日常穿搭的博主&#xff0c;我在后台收到了很多粉丝的询问&#xff0c;大家都休息知道哪个品牌的裤子质量更好&#xff0c;而且风格能够适合男生。而且我注意到很多粉丝习惯于在网红直播间下单&#xff0c;对裤子的品牌以及基本品质并不够了解&#xff0c;所…

suno有了新对手udio炸裂音乐圈;又一个开源AI Devin 程序员;完全开源轻量级的文本到语音可生成特定说话者的风格

✨ 1: udio 由音乐和科技界重量级人物支持的强大 AI 音乐生成器&#xff0c;被称为音乐界的另一个 ChatGPT。 Udio 由前 Google DeepMind的研究院和工程师创立&#xff0c;得到了a16z的支持&#xff0c;总部在伦敦和纽约。 目前是一个免费的V1测试版产品&#xff0c;每个人每…

缺失msvcr110.dll要怎么处理?快捷的修复msvcr110.dll方法

当你在使用电脑进行工作或娱乐时&#xff0c;可能会突然遇到一个错误提示&#xff1a;“程序无法启动&#xff0c;因为电脑中缺失msvcr110.dll”。这样的情况不仅会打断你的活动&#xff0c;还可能带来一定程度的不便。面对这个在Windows操作系统中相对常见的问题&#xff0c;其…

c++语言增强的地方

目录 1.对全局变量的检测能力 2.struct类型增强 3.c中所有变量和函数都必须有类型 4.c中新增的bool类型 5.三目运算符的加强 6.const的增强 7.对枚举的增强 1.对全局变量的检测能力 C语言中同时定义两个相同的全局变量编译器并不会报错&#xff0c;而c中就会报重定义错…

在隐私计算应用中和数链具备哪些技术特点?

在加速“可信数字化”进程的背景下&#xff0c;我国区块链产业将在打造新型平台经济&#xff0c;开启共享经济新时代的同时&#xff0c;带动数字经济“脱虚向实”服务实体经济。 和数软件在加速数字化进程的同时&#xff0c;进一步服务实体经济&#xff0c;提高实体经济的活力…

抖音IP打造品牌规划流量运营方案推广计划书

【干货资料持续更新&#xff0c;以防走丢】 抖音IP打造品牌规划流量运营方案推广计划书 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 50页可编辑&#xff08;完整资料包含以下内容&#xff09; 目录 详细的抖音运营方案&#xff0c;帮助品牌在抖音平台上提升…

如何切换PHP版本

如果服务器上安装了多个php&#xff0c;可能会导致默认的php版本错误&#xff0c;无法启动swoole等服务&#xff0c; 查看命令行的php版本方法&#xff1a;https://q.crmeb.com/thread/9921 解决方法如下&#xff0c;选一个即可&#xff1a; 一、切换命令行php版本&#xff0c…