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

news2024/11/25 10:43:26

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、vcenter
    10、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){
                //预读本地文件示例,不支持ie8
                obj.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

   /*
    * 方法一:配置图片的虚拟路径
    * */
    @Override
    public 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

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

    }

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

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

相关文章

[实例] Unity Shader 利用顶点着色器模拟简单水波

我们都知道顶点着色器可以用来改变模型各个顶点的位置&#xff0c;那么本篇我们就利用顶点着色器来做一个模拟简单水波的应用。 1. 简谐运动 在进行模拟水波之前&#xff0c;我们需要了解简谐运动&#xff08;Simple Harmonic Motion&#xff09;公式&#xff1a; 其中&#…

有公网IP的好处?

1. 维护远程连接需求的解决方案 公网IP是指可以通过互联网直接访问的IP地址&#xff0c;相对于私有IP地址而言具有重要的好处。公网IP的最大好处之一是解决了各行业客户的远程连接需求。由于天联组网操作简单、跨平台应用、无网络要求以及独创的安全加速方案等原因&#xff0c…

Python 全栈体系【四阶】(三十八)

第五章 深度学习 八、目标检测 3. 目标检测模型 3.2 YOLO 系列 3.2.1 YOLOv1&#xff08;2016&#xff09; 3.2.1.1 基本思想 YOLO&#xff08;You Only Look Once &#xff09;是继 RCNN&#xff0c;fast-RCNN 和 faster-RCNN 之后&#xff0c;Ross Girshick 针对 DL 目…

人工智能论文:BERT和GPT, GPT-2, GPT-3 的简明对比和主要区别

在BERT的论文里面&#xff1a; 2018.10 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&#xff0c;BERT已经解释了BERT&#xff0c;GPT&#xff0c;ELMo的区别。 *ELMo为双向RNN&#xff0c;请忽略。 主要区别&#xff1a; BERT使用的是…

Qt QLCDNumber详解

1.简介 它提供了一个显示数字的显示屏控件&#xff0c;效果类似于现实世界中的液晶显示屏。它可以显示任何大小的数字。它可以显示十进制、十六进制、八进制或二进制数字。可以用setMode更改基数&#xff0c;用setSmallDecimalPoint更改小数点。 2.常用方法 以下是一些常用的…

nginx--第三方模块安装上传下载服务

第三方模块安装 准备 cd /usr/local/src/ yum install git -y git clone https://github.com/openresty/echo-nginx-module.git cd nginx-1.24.0 yum -y install perl-devel perl-ExtUtils-Embed zlib-devel gcc-c libtool openssl openssl-devel 编译安装 ./configure \--p…

【深度学习基础(2)】深度学习之前:机器学习简史

文章目录 一. 深度学习的起源1. 概率建模--机器学习分类器2. 早期神经网络--反向传播算法的转折3. 核方法 -- 忽略神经网络4. 决策树、随机森林和梯度提升机5. 神经网络替代svm与决策树 二. 深度学习与机器学习有何不同 可以这样说&#xff0c;当前工业界所使用的大部分机器学习…

Web安全研究(七)

NDSS 2023 开源地址&#xff1a;https://github.com/bfpmeasurementgithub/browser-fingeprint-measurement 霍普金斯大学 文章结构 introbackground threat model measurement methodology step1: traffic analysisstep2: fingerprint analysis dataset attack statisticsbro…

【通信中间件】Fdbus HelloWorld实例

Fdbus实例教程 Fdbus简介 Fdbus 全称 Fast Distributed Bus&#xff08;高速分布式总线&#xff09;&#xff0c;提供IPCRPC功能。适用于多种OS&#xff1a; LinuxQNXAnroidOSWindow Fdbus本质是Socket&#xff0c;IPC基于Unix domain socket&#xff0c;RPC基于TCP。使用G…

诺基亚贝尔探访上海斯歌,共探创新合作新机遇

近日&#xff0c;上海斯歌K2 BPM迎来重要客户考察交流活动。来自诺基亚贝尔的首席数字官刘少勇一行莅临了上海斯歌K2 BPM 的武汉研发中心&#xff0c;并对上海斯歌在BPM业务流程管理领域的研发成果及交付能力给予了高度肯定。 此次活动不仅加深了双方的战略合作&#xff0c;也为…

【机器学习基础1】什么是机器学习、预测模型解决问题的步骤、机器学习的Python生态圈

文章目录 一. 什么是机器学习1. 概念2. 机器学习算法分类 二. 利用预测模型解决问题的步骤三. 机器学习的Python生态圈 一. 什么是机器学习 1. 概念 机器学习&#xff08;Machine Learning&#xff0c;ML&#xff09;是一门多领域的交叉学科&#xff0c;涉及概率论、统计学、…

Librosa:探索音频处理利器

Librosa&#xff1a;探索音频处理利器 音频处理在数据科学、音乐分析和语音识别等领域中扮演着重要角色。Python库Librosa是一个功能强大且广泛使用的工具&#xff0c;专门用于音频分析和处理。本文将介绍Librosa库的基本概念、主要功能以及常见应用场景&#xff0c;帮助读者深…

银行卡归属地查询API接口快速对接

银行卡归属地查询API接口指的是通过银行卡号查询该银行卡详细信息&#xff0c;包括银行卡名称、卡种、卡品牌、发卡行、编号以及归属地等信息&#xff0c;支持一千多家银行返回归属地信息&#xff0c;那么银行卡归属地查询API接口如何快速对接呢&#xff1f; 首先找到有做银行…

【linux-汇编-点灯之思路-程序】

目录 1. ARM汇编中的一些注意事项2. IMXULL汇编点灯的前序&#xff1a;3. IMXULL汇编点灯之确定引脚&#xff1a;4. IMXULL汇编点灯之引脚功能编写&#xff1a;4.1 第一步&#xff0c;开时钟4.2 第二步&#xff0c;定功能&#xff08;MUX&#xff09;4.3 第三步&#xff0c;定电…

Qt5 框架学习及应用 — 对象树

Qt 对象树 对象树概念Qt为什么使用对象树 &#xff1f;将对象挂到对象树上 对象树概念 对象树&#xff1a;对于树的概念&#xff0c;相信许多学过数据结构的同学应该都不会陌生。在学习数据结构的时候我们所接触的什么二叉树、多叉树、哈夫曼树、AVL树、再到红黑树、B/B树………

【C++中的模板】

和你有关&#xff0c;观后无感................................................................................................................. 目录 前言 一、【模板的引入和介绍】 1、泛型编程 2、【模板的介绍】 二、【 函数模板】 2.1【模函数板的介绍】 1.…

win11 Terminal 部分窗口美化

需求及分析&#xff1a;因为在 cmd、anaconda prompt 窗口中输入命令较多&#xff0c;而命令输入行和输出结果都是同一个颜色&#xff0c;不易阅读&#xff0c;故将需求定性为「美化窗口」。 美化结束后&#xff0c;我在想是否能不安装任何软件&#xff0c;简单地通过调整主题颜…

STM32——点亮第一个LED灯

代码示例&#xff1a; #include "stm32f10x.h" // Device headerint main() {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitSt…

头歌实践教学平台:投影变换v2.0

第2关&#xff1a;两点透视 一. 任务描述 1. 本关任务 (1) 理解透视投影变换的方法; (2) 将main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为1的obj正方体模型&#xff0c;具体模型如下图&#xff1a; (2) 代码自动将模型投影到二维平面中心生成一个…

【MySQL | 第十篇】重新认识MySQL索引匹配过程

文章目录 10.重新认识MySQL索引匹配过程10.1匹配规则10.2举例&#xff1a;联合索引遇到范围查询&#xff08;>、<、between、like&#xff09;10.2.1例子一&#xff1a;>10.2.2例子二&#xff1a;>10.2.3例子三&#xff1a;between10.2.4例子四&#xff1a;like 10…