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、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/");

    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IP定位技术企业网络安全检测

随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显&#xff0c;成为企业运营中不可忽视的一环。在众多网络安全技术中&#xff0c;IP定位技术以其独特的优势&#xff0c;为企业网络安全检测提供了强有力的支持。本文将深入探讨IP定位技术在企业网络安全检测中的应用及其…

QT学习之读取xml中信息

背景&#xff1a; 我们每次注册后会生成对应的启动码文件&#xff0c;格式如下&#xff0c;启动码最后要在测试工具使用的进行一个验证&#xff0c;验证通过后模块才能使用。所以我希望每次的xml都放在一个文件夹里&#xff0c;等我选择文件夹后&#xff0c;能提取所有xml中的对…

手把手教会西门子PLC代码可视化功能——Prodiag

一、传统的HMI报警方法 在HMI中建立离散量报警&#xff0c;输入报警文本。这种方法的劣势&#xff1a; 1、在PLC程序中需要建立专门报警程序&#xff0c;用于关联HMI中的报警变量 2、需要在HMI文本中输入报警文本 如果程序复杂&#xff0c;报警众多&#xff0c;用这种方法需…

性能监控之prometheus+grafana搭建

前言 Prometheus和Grafana是两个流行的开源工具&#xff0c;用于监控和可视化系统和应用程序的性能指标。它们通常一起使用&#xff0c;提供了强大的监控和数据可视化功能。 Prometheus Prometheus是一种开源的系统监控和警报工具包。它最初由SoundCloud开发&#xff0c;并于…

二分查找法实例

本文是根据数据结构中常常提到的二分法而作的一篇博客&#xff0c;主要通过一个二分法实例进行展开说明&#xff1a; 实例内容 通过一个二分法函数来寻找某个数是否在给定的数组中&#xff1b; 代码展示 # 执行二分查找法的算法函数 # 二分法查找的对象必须是一个有序的集…

尼日利亚光伏储能展

尼日利亚地处热带地区&#xff0c;全年阳光充足&#xff0c;每年日照时间超2600小时(平均每天约7小时)。专家表示&#xff0c;尼日利亚有足够的经济实力和环境条件来开发可再生能源&#xff0c;尤其是太阳能。据世界银行估计&#xff0c;投资太阳能发电厂可为近8000万人提供电力…

短视频交友系统搭建重点,会用到哪些三方服务?

在搭建短视频交友系统时&#xff0c;为了确保系统的稳定性、安全性和用户体验&#xff0c;通常需要用到多种第三方服务。以下是搭建短视频交友系统时可能用到的关键第三方服务&#xff1a; 云服务提供商&#xff1a;如阿里云、腾讯云等&#xff0c;提供稳定、可扩展的服务器资源…

Web前端一套全部清晰 ⑤ day3 列表 表格 表单标签 综合案例

人生是一直向前无法倒退的旅程&#xff0c;所以可以偶尔回头&#xff0c;但一定要往前看 —— 24.4.29 一、综合案例1-体育新闻列表 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport…

优化NGINX性能:使用NGINX_THREADS提高并发处理能力

目录标题 1. 什么是NGINX_THREADS&#xff1f;2. 配置NGINX_THREADS3. 使用NGINX_THREADS处理耗时操作4. 性能调优5. 结论 NGINX作为一个高性能的HTTP和反向代理服务器&#xff0c;在处理高并发请求时表现出色。但随着互联网应用对性能要求的不断提高&#xff0c;深入了解和优化…

AOSP源码开发

AOSP源码开发 Author: cpu_codeDate: 2020-07-11 16:18:27LastEditTime: 2020-07-12 21:08:41FilePath: \note\android_bottom\summary.mdGitee: https://gitee.com/cpu_codeGithub: https://github.com/CPU-CodeCSDN: https://blog.csdn.net/qq_44226094Gitbook: https://923…

【Leetcode每日一题】 综合练习 - 找出所有子集的异或总和再求和(难度⭐)(68)

1. 题目解析 题目链接&#xff1a;1863. 找出所有子集的异或总和再求和 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 算法思路与实现 为了求解给定整数数组的所有子集并将其异或和相加&#xff0c;我们可以采用递…

【GO】命令行解析 os 与 flag

目录 OS解析命令 简单用法 进阶用法 flag命令解析 基础实例 1. 自定义数据类型 2. 创建多个 FlagSet 3. 整合环境变量和配置文件 os与flag 关键点解析 程序的作用 示例命令行调用 在 Go 语言中&#xff0c;命令行解析是一项基本且常用的功能&#xff0c;它允许开发者…

【Linux系统编程】第十一弹---编辑器vim使用

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、vim的基本概念 2、vim的基本操作 3、vim插入模式命令集 4、vim正常(命令)模式命令集 5、vim末行模式命令集 6、vim操作…

C/C++程序设计实验报告综合作业 | 小小计算器

本文整理自博主本科大一《C/C程序设计》专业课的课内实验报告&#xff0c;适合C语言初学者们学习、练习。 编译器&#xff1a;gcc 10.3.0 ---- 注&#xff1a; 1.虽然课程名为C程序设计&#xff0c;但实际上当时校内该课的内容大部分其实都是C语言&#xff0c;C的元素最多可能只…

mac用Homebrew安装MySQL并配置远程登录

1. 简介 MySQL 是一个开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典 MySQL AB 公司开发&#xff0c;后被 Oracle 公司收购。MySQL 使用 SQL&#xff08;Structured Query Language&#xff09;作为查询语言&#xff0c;并提供了强大的功能和性能…

鸿蒙开发面试真题——面向对象

鸿蒙开发面向对象的面试题是近年来在软件开发领域中备受关注的话题。作为一种新兴的操作系统&#xff0c;鸿蒙系统的开发者需要具备扎实的面向对象编程知识和丰富的开发经验。在面试中&#xff0c;面试官常常会通过一系列的问题来考察面试者对于鸿蒙开发面向对象的理解和应用能…

ES 深度分页问题及针对不同需求下的解决方案[ES系列] - 第509篇

历史文章&#xff08;文章累计500&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《…

春游江淮 请来池州 | 五一池州文旅活动时间表大集合,都在这里

快到五一,想好去哪里玩吗?来池州,各景区缤纷活动登场&#xff0c; 速速划重点、敲黑板! 五一放大招!到底怎么玩?文旅活动、阅读推广 非遗展示......现在都已经为你整理好啦!这份超齐全的 五一假期文旅活动时间表,助力您玩转各景区,整个假期嗨不停~ 旅游惠民活动 表演类活动…

salesforce 如何访问lwc组件

访问lwc有哪些途径呢? Action ButtonTabAura use lwc(拓展)如何区分是新建页面还是编辑页面 Action Button xml文件中要配置tab<?xml version"1.0" encoding"UTF-8"?> <LightningComponentBundle xmlns"http://soap.sforce.com/2006/04/…

使用fitten code插件(vscode),替换通义千问,识别需求中的输入输出

今天我们介绍一个工具,具体介绍可以参考我的这篇文章的介绍,支持vs code 插件,Fitten Code是一款由非十科技开发的AI代码助手,旨在通过大模型驱动来提升编程效率和体验-免费神器-CSDN博客https://blog.csdn.net/lijigang100/article/details/137833223?spm=1001.2014.3001…