SpringBoot实现图片上传(个人头像的修改)

SpringBoot+layui实现个人信息头像的更改

该文章适合对SpringBoot,Thymeleaf,layui入门的小伙伴
废话不多说,直接上干货

Springboot+layui实现头像更换

前端公共部分代码

HTML页面代码

 	 <div class="layui-card-header" style="height: 215px"><div id="div-avatar"><a th:href="${'../'+session.account.getAvatar()}" target="_blank"><img id="img" th:src="${'../'+session.account.getAvatar()}" alt="暂无图片"></a></div><button style="display: block; margin: 12px auto;"class="layui-btn layui-bg-green layui-btn-xs avatar" lay-on="avatarBtn"><i class="fa fa-camera-retro"></i> 更换头像</button></div>

在这里插入图片描述

js部分代码(点击更换头像按钮弹出上传图片的弹窗,点击保存按钮实现图片的更新操作)

<script th:src="@{../dist/notify/notify.js}"></script>
<script>layui.use(['form', 'miniTab','notify'], function () {var form = layui.form,layer = layui.layer,miniTab = layui.miniTab;var util = layui.util;var notify=layui.notify;/** lay-on实现关闭按钮,及头像修改界面* */util.on('lay-on', {/** 点击avatarBtn弹出头像修改界面* */"avatarBtn": function () {layer.open({type: 2 //此处以iframe举例, title: '修改头像', area: ['490px', '460px'], shade: 0, maxmin: true, offset: 'auto' //为了演示,这里设置不固定], content: '/page/upload', btn: ['保存', '关闭'] //只是为了演示, yes: function () {notify.loading("正在验证头像图片合法性,请稍后","vcenter","shadow",false)setTimeout(function () {notify.destroyAll();//关闭loading$.ajax({type: 'PUT',url: "/auth/updateAvatar",//实现头像success: function (d) { // 返回的RequestResult的json对象if (d.code === 0) {//弹出成功提示框,notify.success(d.msg,"vcenter","shadow",false);}else if (d.code === 1){//如果信息一致,弹出提示框notify.warning(d.msg, "vcenter","shadow",false);}else {notify.error(d.msg,"vcenter","shadow",false);}},}).done(function () {setTimeout(function () {notify.destroyAll(); //全部关闭setTimeout(function () {miniTab.deleteCurrentByIframe();}, 1000);}, 2500);});}, 3000);return false;}, btn2: function () {layer.closeAll();}});}});});
</script>
<!--第三方插件介绍使用1、notify.info("提示消息");2、notify.warning("警告消息");3、notify.success("成功消息");4、notify.loading("加载中");5、notify.error("失败消息");6、notify.info("不显示关闭按钮", false);7、notify.warning("提示消息", function () {alert("回调成功");});8、notify.destroyAll(); //全部关闭9、notify.success("指定位置显示", "topLeft"); //参数:topLeft、topCenter、topRight、bottomLeft、bottomCenter、bottomRight、vcenter10、notify.alert("模态框", "vcenter","shadow"); //参数:shadow 显示遮罩11、notify.confirm("确认框", "vcenter","shadow"function(){alert("回调方法")}); //参数:shadow 显示遮罩 、function 确定后回调方法
-->

在这里插入图片描述

上传图片的upload.html文件

<!DOCTYPE html>
<html class="x-admin-sm" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>头像上传</title><link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/><link rel="stylesheet" th:href="@{../layui/css/layui.css}"><link rel="stylesheet" th:href="@{../css/public.css}" media="all">
</head>
<body>
<div class="layuimini-container"><div class="layuimini-main"><div class="layui-upload-drag" style="display: block;" id="upload-avatar"><i class="layui-icon layui-icon-upload"></i><div>点击上传,或将文件拖拽到此处</div><div class="layui-upload-list"><hr> <img class="layui-upload-img" id="upload-preview" style="max-height: 260px;max-width: 260px"><p id="avatarText"></p></div></div></div>
</div>
<script th:src="@{../layui/layui.js}" charset="utf-8"></script>
<script th:src="@{../js/jquery-3.7.1.min.js}"></script>
<script type="text/javascript">layui.use(function(){var upload = layui.upload;var $ = layui.$;// 渲染var uploadInst = upload.render({elem: '#upload-avatar'//只要是上传图片 都用这一个接口,url: "/auth/uploadImage",before: function(obj){//预读本地文件示例,不支持ie8obj.preview(function(index, file, result){$('#upload-preview').attr('src', result); //图片链接(base64)console.log(result)});},done: function(res){//如果上传失败if(res.code >0){return layer.msg('上传失败');}//上传成功else{layer.msg('上传成功');console.log(res.data.src)}},error: function(){//演示失败状态,并实现重传var avatarText = $('#avatarText');avatarText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');avatarText.find('.demo-reload').on('click', function(){uploadInst.upload();});}});});
</script></body>
</html>

在这里插入图片描述

图片上传点击js中的保存按钮实现图片的更新保存( 公共后端代码)

controller

 /** 更新头像* updateAvatar* */@PutMapping("/updateAvatar")public ResultUtil updateAvatar() {// 获取当前登录人的信息ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 获取请求HttpServletRequest request = attributes.getRequest();// 获取当前登录人的信息UserEntity userEntity = (UserEntity) request.getSession().getAttribute("account");// 获取头像String avatar = (String) request.getSession().getAttribute("filename");// 打印测试System.out.println("头像:"+avatar);if (userEntity != null) {if (avatar != null){// 设置头像String avatarPath= "images/avatar/"+avatar;userEntity.setAvatar(avatarPath);// 更新头像userService.accountInformation(userEntity);// 返回成功信息return ResultUtil.ok(0, "头像修改成功");}return ResultUtil.warning(1,"头像不能为空哦!");}// 返回失败信息return ResultUtil.error("头像修改失败");}

方法一(上传图片在项目中)

loginController代码

 /** 个人头像图片上传* 方法一对应WebConfigurer 中的方法一* */@PostMapping("/uploadImage")public Map<String, Object> image(@RequestParam(value = "file") MultipartFile file,HttpSession session){Map<String, Object> map2 = new HashMap<String, Object>();Map<String, Object> map = new HashMap<String, Object>();String filename = "";//存放上传的图片在项目中的路径String localPath = System.getProperty("user.dir") + "/src/main/resources/static/images/avatar/";try {if (file != null) {//生成uuid作为文件名称String uuid = UUID.randomUUID().toString().replaceAll("-", "");//获得文件类型(可以判断如果不是图片,禁止上传)String contentType = file.getContentType();//获得文件后缀名String suffixName = contentType.substring(contentType.indexOf("/") + 1);//得到 文件名(随机数+uuid+后缀)filename = (int)((Math.random())*100000000) + uuid + "." + suffixName;//将生成的图片名称保存到session中session.setAttribute("filename", filename);//复制到项目中的文件夹Path path = Paths.get(localPath + filename);session.setAttribute("path", path);System.out.println("图片上传路径:"+path);Files.write(path, file.getBytes());}} catch (Exception e) {map.put("code", 1);map.put("msg", "");map.put("data", map2);map2.put("src", filename);return map;}map.put("code", 0);map.put("msg", "");map.put("data", map2);map2.put("src", filename);return map;}

WebConfigurer 拦截器中的方法将静态资源释放否则项目上传以后无法进行访问会出现404

   /** 方法一:配置图片的虚拟路径* */@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {//这里配置图片的虚拟路径 注意数据库存放的图片是 images/avatar/***.jpg 这种格式"file:E:/IDEAWork/ERP_Project/src/main/resources/static/images/avatar/"registry.addResourceHandler("/images/avatar/**").addResourceLocations("file:E:/IDEAWork/ERP_Project/src/main/resources/static/images/avatar/");}

方法二(单独新建文件夹来存放照片)

controller代码

 @RequestMapping(value = "/uploadImage", method = {RequestMethod.POST})public Map<String, Object> upload(MultipartFile file,HttpServletRequest request ,HttpSession session){String filename=file.getOriginalFilename();String uuid = UUID.randomUUID()+"";//这里填上传到本地的路径File dest = new File(new File("D:\\erp_img").getAbsolutePath()+ "/" + uuid+"-"+filename);if (!dest.getParentFile().exists()) {dest.getParentFile().mkdirs();}try {file.transferTo(dest);String path="images/avatar/"+uuid+"-"+filename;session.setAttribute("path",path);System.out.println(path);Map<String,Object> map2=new HashMap<>();Map<String,Object> map=new HashMap<>();map.put("code",0);map.put("msg","");map.put("data",map2);map2.put("src",path);return map;} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}Map<String,Object> map=new HashMap<>();map.put("code",1);map.put("msg","");return map;}

WebConfigurer

 @Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {//这里配置图片的虚拟路径 注意数据库存放的图片是 images/avatar/***.jpg 这种格式registry.addResourceHandler("/images/avatar/**").addResourceLocations("file:D:/erp_img/");}

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

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

相关文章

20240502解决ARM32编译器编译quectel-CM时for循环出错的解决

20240502解决ARM32编译器编译quectel-CM时for循环出错的解决 2024/5/2 17:17 缘起&#xff1a;QMIThread.c:2100:9: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode 1、修改Makefile为ARM32架构&#xff1a; Z:\quectel-CM\Makefile ifneq ($…

基于SpringBoot+Vue的旅游网站系统

初衷 在后台收到很多私信是咨询毕业设计怎么做的&#xff1f;有没有好的毕业设计参考?能感觉到现在的毕业生和当时的我有着同样的问题&#xff0c;但是当时的我没有被骗&#xff0c;因为现在很多人是被骗的&#xff0c;还没有出学校还是社会经验少&#xff0c;容易相信别人。…

【算法设计与分析】实验报告c++python实现(TSP问题、哈夫曼编码问题、顾客安排问题、最小生成树问题、图着色问题)

一、实验目的 1&#xff0e;加深学生对贪心算法设计方法的基本思想、基本步骤、基本方法的理解与掌握&#xff1b; 2&#xff0e;提高学生利用课堂所学知识解决实际问题的能力&#xff1b; 3&#xff0e;提高学生综合应用所学知识解决实际问题的能力。 二、实验任务 用贪心算…

Spring基于AspectJ实现验签切点

文章目录 引言I AspectJ 依赖II 验签切点2.1 匹配方法执行的连接点2.2 设置带有CustomAnnotation注解的方法为切点III 案例:验签2.1 用法2.2 定义注解2.3 定义切面和切点引言 需求:验签 实现:基于AspectJ实现验签切点 I AspectJ 依赖 AspectJ 是一个基于 Java 语言的 AOP …

go稀疏数组

稀疏数组 稀疏数组 稀疏数组 package testimport ("encoding/json""fmt""io/ioutil""log""reflect""testing" )type ValNode struct {Row int json:"row"Col int json:"col"Val int json:&qu…

Spring Cloud Kubernetes 实践 服务注册发现、服务动态配置

一、Spring Cloud Kubernetes 随着云计算和微服务架构的不断发展&#xff0c;k8s 和Spring Cloud成为了当今技术领域的两大热门话题。k8s作为一个开源的容器编排平台&#xff0c;已经在自动化部署、扩展和管理方面取得了巨大的成功&#xff0c;而Spring Cloud则以其丰富的生态…

MFC 列表控件修改实例(源码下载)

1、本程序基于前期我的博客文章《MFC下拉菜单打钩图标存取实例&#xff08;源码下载&#xff09;》 2、程序功能选中列表控件某一项&#xff0c;修改这一项的按钮由禁止变为可用&#xff0c;双击这个按钮弹出对话框可对这一项的记录数据进行修改&#xff0c;点击确定保存修改数…

基于Spring Boot的体质测试数据分析及可视化系统设计与实现

基于Spring Boot的体质测试数据分析及可视化系统的设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 前台首页界面图&#xff0c;体质测试…

Github查找代码项目高级语法(含科研项目查找案例)

基础搜索语法 1.搜索名字 in:name XXX 2.搜索描述 in:description XXX 3.搜索readme in:readme XXX 4.根据stars stars:>2000 5.根据fork fork:>3000 6.仓库大小搜索 size:>5000 [注意: 该处单位大小为 k] 7.根据更新时间 …

免费开源语音克隆-GPT-SoVITS-WebUI只需 5 秒的声音样本

语音克隆-GPT-SoVITS-WebUI 强大的少样本语音转换与语音合成Web用户界面。 功能&#xff1a; 零样本文本到语音&#xff08;TTS&#xff09;&#xff1a; 输入 5 秒的声音样本&#xff0c;即刻体验文本到语音转换。 少样本 TTS&#xff1a; 仅需 1 分钟的训练数据即可微调模型…

OpenCV如何在图像中寻找轮廓(60)

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV如何模板匹配(59) 下一篇 :OpenCV检测凸包(61) 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 cv::findContours使用 OpenCV 函数 cv::d rawContours …

【Flask 系统教程 4】Jinjia2模版和语法

Jinjia2 模板 模板的介绍 Jinja2 是一种现代的、设计优雅的模板引擎&#xff0c;它是 Python 的一部分&#xff0c;由 Armin Ronacher 开发。Jinja2 允许你在 HTML 文档中嵌入 Python 代码&#xff0c;以及使用变量、控制结构和过滤器来动态生成内容。它的语法简洁清晰&#…

【Qt QML】用CMake管理Qt工程

CMake是一个开源、跨平台的工具系列&#xff0c;用于构建、测试和打包软件。CMake使用简单的独立配置文件来控制软件编译过程。与许多跨平台系统不同&#xff0c;CMake被设计为与本地构建环境结合使用。 下面我们在CMake项目中使用Qt的最基本方法。首先&#xff0c;创建一个基本…

系统架构设计师错题集

在实时操作系统中&#xff0c;两个任务并发执行&#xff0c;一个任务要等待另一个任务发来消息&#xff0c;或建立某个条件后再向前执行&#xff0c;这种制约性合作关系被称为任务的&#xff08;9&#xff09;。 (9)A.同步 B.互斥 C.调度 D.执行 【答案】A 【解析】本题考查…

Linux图形化界面怎么进入?CentOS 7图形界面切换

CentOS 7默认只安装命令行界面。要切换到图形界面&#xff0c;需要先检查系统是否安装图形界面&#xff0c;在终端输入以下命令&#xff1a; systemctl get-default若是返回结果是“multi-user.target”表示系统没有安装图形界面&#xff1b;若是返回结果是“graphical.target…

Linux migrate_type进一步探索

文章接着上回Linux migrate_type初步探索 1、物理页面添加到buddy系统 我们都知道物理内存一开始是由memblock进行分配管理&#xff0c;后面会切换到buddy系统管理。那么接下来我们看一下&#xff0c;memblock管理的物理页面是怎么添加到buddy系统中的。 start_kernel() -&g…

双指针(C++)

文章目录 1、移动零2、复写零3、快乐数4、盛最多水的容器5、有效三角形的个数6、和为s的两个数7、三数之和8、四数之和 需要理解的是&#xff0c;双指针并非只有指针&#xff0c;双指针的意思是两个位置。比如对于数组来说&#xff0c;两个下标也是双指针。当然&#xff0c;也可…

merge and rebase

文章目录 什么是merge什么是rebasemerge和rebase的区别操作执行git merge操作git rebase操作冲突解决解决冲突的步骤 Git Merge 和 Git Rebase 都是用于集成来自不同分支的修改的 Git 命令。 什么是merge Git Merge 是将一个分支的改动合并到另一个分支的方式。当你执行一个 m…

LabVIEW机械臂控制与图像处理示教平台

LabVIEW机械臂控制与图像处理示教平台 随着工业自动化技术的快速发展&#xff0c;工业机器人在制造业中的应用越来越广泛&#xff0c;它们在提高生产效率、降低人工成本以及保证产品质量方面发挥着重要作用。然而&#xff0c;传统的工业机器人编程和操作需要专业知识&#xff…

2024-5-3学习笔记 虚拟继承原理

目录 原理 总结 前面提到过&#xff0c;解决菱形继承产生的数据二义性问题和数据冗余&#xff0c;就需要用到虚拟继承&#xff0c;关于它是如何解决的&#xff0c;我们来一起研究。 class Person { public :string _name ; // 姓名 }; class Student : virtual public Perso…