个人中心 - 实现修改用户头像、用户名或密码

2023-11-09

目录

1. 修改用户头像

1.1 获取原来的用户头像和用户名

1.2 实现保存头像

2. 修改用户名或密码


1. 修改用户头像

本文是针对之前的一篇项目博客 - 博客系统 做的一个扩展功能.

1.1 获取原来的用户头像和用户名

想要修改头像, 那么就得先获取数据库中原来的头像, 此处顺便将原用户名一起获取并展示出来. 原密码最好不要获取出来, 因为有可能你在修改密码的中途, 你去上厕所了, 然后你的密码被你好兄弟给修改了. 

大致效果 : 

前端展示页面相关代码

<div class="row" style="margin-top: 70px;margin-bottom: 50px;">
    <img id="photo" src="img/bg2.jpg"
            style="width: 100px;height: 115px;">
    <input id="file" style="font-size: 12px;width: 120px;" type="file">
    <button style="width: 80px;height: 50px;" onclick="savePhoto()">保存</button>
</div>
<div class="row">
    <span>用户名</span>
    <input type="text" id="username">
</div>
<div class="row">
    <span>原密码</span>
    <input type="password" id="old_password">
</div>
<div class="row">
    <span>新密码</span>
    <input type="password" id="password">
</div>
<div class="row">
    <span>确认密码</span>
    <input type="password" id="password2">
</div>
<div class="row" style="margin-top: 10px;">
    <button id="submit" onclick="updateUser()">修 改</button>
</div>

写前端 js 代码

// 获取用户头像和昵称
function initPage() {
    jQuery.ajax({
        url:"/user/myinfo",
        type:"GET",
        data:{},
        success:function(body) {
            if(body.code==200 && body.data!=null && body.data.id>=0) {
                // 得到了当前的 userinfo
                var userinfo = body.data
                if(userinfo.photo!=null && userinfo.photo!="") {
                    jQuery("#photo").attr("src",userinfo.photo);
                }
                jQuery("#username").val(userinfo.username);
            } else {
                alert("抱歉: 查询用户信息出错, 请刷新页面再试! " + body.msg);
            }
        }
    });
}
initPage();

1. 获取当前登录人的用户名和头像, 只需在后端的 session 中拿到具体的 userinfo 即可.

2. sucess 回调函数中的注意事项:  因为我们在构造数据 (userinfo) 的时候, 头像一般都是写死的本地图片, 所以新用户一般都是默认头像, 所以我们在操作 dom 树构造 photo 的 src 属性时, 一定要判断 photo 是否为 null 或者是否为 "", 如果是就不要设置 photo 的 src 属性, 否则会导致用户没有头像.

写后端代码

@RequestMapping("/myinfo")
public Object myInfo(HttpServletRequest request) {
    // 从 session 工具类中拿用户登录信息
    UserInfo userInfo = SessionUtil.getLoginUser(request);
    if (userInfo == null || userInfo.getId() <= 0) {
        return AjaxResult.fail(-2,  "当前用户未登录!");
    }
    return AjaxResult.success(userInfo);
}

因为多处代码需要拿 session , 所以将其封装成了一个公共的方法.

1.2 实现保存头像

此处我们上传新的头像后, 并点击保存按钮时, 就是修改头像成功了.

写前端 js 代码 (给保存按钮添加点击事件)

// 保存头像
function savePhoto() {
    // 得到图片
    var photo = jQuery("#file")[0].files[0];
    if (photo == null) {
        alert("请先选择要上传的头像!");
        return false;
    }
    // 构建一个 form 表单
    var formData = new FormData();
    formData.append("file", photo);
    jQuery.ajax({
        url:"/user/save_photo",
        type:"POST",
        data:formData,
        processData:false, // 告诉 jQuery 不要去加工数据
        contentType:false, // 告诉 jQuery 不要设置类型
        success:function(body) {
            if(body.code==200 && body.data!=null && body.data!="") {
                jQuery("#photo").attr("src",body.data);
            } else {
                // 图片上传失败
                alert("抱歉: 上传图片失败, 请重试! " + body.msg);
            }
        }
    });
}

1. 此处的得到图片代码比较特殊

2. 发送 ajax 时, 参数是发送一个 form 表单给后端, 所以 ajax 中需要多添加两个参数 : processData 和 contentType.

3. 表单传给后端时, 后端针对图片生成一个网络地址映射到本地保存的地址, 然后将网络地址返回给前端, 前端操作 dom 树将其设置给 photo 的 src 属性.

写后端代码

1. 配置映射图片的路径

在配置文件中 application.properties 指定保存头像的本地路径 :

imagepath=D:/image/

在添加拦截规则的类里边加上 addResourceHandlers 类 :

@Value("${imagepath}")
private String imagepath;
**
 * 映射图片路径
 * @param registry
 */
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/image/**")
            .addResourceLocations("file:" + imagepath + "/");
}

2. 保存图片到服务器, 保存图片地址到数据库

@RequestMapping("/save_photo")
public Object savePhoto(MultipartFile file, HttpServletRequest request) {
    // 1.保存图片到服务器
    // 得到图片的后缀
    String imageType = file.getOriginalFilename().
            substring(file.getOriginalFilename().lastIndexOf("."));
    // 生成图片的名称
    String imgName = UUID.randomUUID().toString()
            .replace("-", "") + imageType;
    try {
        file.transferTo(new File(imagePath + imgName));
    } catch (IOException e) {
        return AjaxResult.fail(-1, "图片上传失败!");
    }
    String imgUrl = "/image/" + imgName;
    // 2.将图片地址保存到数据库
    UserInfo userInfo = SessionUtil.getLoginUser(request);
    if(userInfo == null || userInfo.getId() <= 0) {
        return AjaxResult.fail(-2, "请先登录! ");
    }
    // 修改头像
    int result = userService.updatePhoto(userInfo.getId(),imgUrl);
    if(result == 1) {
        // 将用户的头像更新到 session 中
        userInfo.setPhoto(imgUrl);
        HttpSession session = request.getSession();
        session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);
        return AjaxResult.success(imgUrl);
    } else {
        return AjaxResult.fail(-3, "数据库修改失败! ");
    }
}

步骤分析

1. 保存图片到服务器

当用户从自己的电脑上选取了一张图片上传时, 后端就需要将用户传来的图片保存到服务器, 然后再生成图片对应的网络地址. 最后将新头像对应的网络地址返回给前端, 前端就可以通过设置头像 photo 对应的 src 属性为返回的网络地址.

2. 保存图片到数据库

修改头像不仅要更新当前页面展示的头像, 数据库中的头像对应的网络地址也要更新, 另外如果更新数据成功了, 要同时更新 session 中的 userinfo 信息. 因为博客列表页的当前用户的身份信息, 后端都是从 session 中取出来返回给前端的, 所以需要同时更新数据库和 session 中的 photo 字段(属性).

此时修改头像操作就已经大功告成了~

2. 修改用户名或密码

此处我们点击个人中心跳转到修改用户信息的页面时, 它只是将头像和用户名展示出来了, 而原密码, 新密码和确认密码需要手动输入(要么三个都不为空 - 改, 要么都为空 - 不改).

  • 如果不修改密码, 只是修改用户名或者都不修改, 然后点击修改按钮, 就提示修改成功, 并跳转到我的内容管理页面.
  • 如果修改了密码, 并点击了修改按钮, 就提示修改成功, 并强制用户重新登录.

写前端 js 代码(给修改按钮添加点击事件)

function updateUser() {
    var isUpdatePassword = false; // 是否修改密码
    // 1.非空效验
    var username = jQuery("#username");
    var oldPassword = jQuery("#old_password");
    var password = jQuery("#password");
    var password2 = jQuery("#password2");
    if (username.val().trim() == "") {
        alert("请先输入新用户名!");
        username.focus();
        return false;
    }
    if (oldPassword.val() != "" ||
        password.val() != "" || password2.val() != "") {
        // 需要修改密码
        isUpdatePassword = true;
        if (oldPassword.val().trim() == "") {
            alert("请先输入原密码!");
            oldPassword.focus();
            return false;
        }
        if (password.val().trim() == "") {
            alert("请先输入新密码!");
            password.focus();
            return false;
        }
        if (password2.val().trim() == "") {
            alert("请先输入确认密码!");
            password2.focus();
            return false;
        }
        // 判断新密码和确认密码是否一致
        if (password.val() != password2.val()) {
            alert("两次输入的新密码不一致,请先确认!");
            return false;
        }
    }
    // 2.将前端的数据提交给后端
    jQuery.ajax({
        url: "/user/update",
        type: "POST",
        data: {
            "username": username.val(),
            "oldPassword": oldPassword.val(),
            "password": password.val(),
            "isUpdatePassword": isUpdatePassword
        },
        success: function (res) {
            // 3.将返回的结果展现给用户
            if (res.code == 200 && res.data == 1) {
                // 修改成功
                if (isUpdatePassword) {
                    alert("修改成功,请重新登录!");
                    // 修改密码,重新登录
                    location.href = "login.html";
                } else {
                    alert("修改成功!");
                    location.href = "myblog_list.html";
                }
            } else {
                // 修改失败
                alert("抱歉:修改失败,请重试!" + res.msg);
            }
        }
    });
}

写后端代码

@RequestMapping("/update")
public Object update(String username, String oldPassword, String password,
                     Boolean isUpdatePassword, HttpServletRequest request) {
    // 1.参数效验
    if(!StringUtils.hasLength(username)) {
        return AjaxResult.fail(-1, "非法参数! ");
    }
    // 是否要修改密码
    if(isUpdatePassword) {
        // 修改原密码
        if(!StringUtils.hasLength(oldPassword) || !StringUtils.hasLength(password)) {
            return AjaxResult.fail(-1, "非法参数! ");
        }
    }
    // 2.组装数据 (从 session 中获取用户信息)
    UserInfo userInfo = SessionUtil.getLoginUser(request);
    if(userInfo == null || userInfo.getId() <= 0) {
        return AjaxResult.fail(-2,"请先登录! ");
    }
    UpdateWrapper<UserInfo> wrapper = new UpdateWrapper<>();
    // 判断两次密码是否一致
    if(isUpdatePassword) {
        // 验证原密码和 session 中的密码是否一致
        UserInfo dbUser = userService.getById(userInfo.getId());
        boolean checkPassword = SaltSecurityUtil.decrypt(oldPassword,dbUser.getPassword());
        if(!checkPassword) {
            return AjaxResult.fail(-3,"原密码输入错误! ");
        }
        // 修改密码
        password = SaltSecurityUtil.encrypt(password);
        wrapper.set("password",password);
    }
    // 3.修改数据库
    wrapper.eq("id",userInfo.getId());
    wrapper.set("username", username);
    boolean result = userService.update(wrapper);
    // 更新 session 中的用户名
    if(result) {
        userInfo.setUsername(username);
        HttpSession session = request.getSession();
        session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);
    }
    // 4.将结果返回给前端
    return AjaxResult.success(result ? 1 : 0);
}

【步骤分析】

1. 非空效验

        前端传递了新用户名, 原密码, 新密码, 以及是否修改了密码的标志, 于是在做判断时, 如果只修改了用户名, 就可以使用 isUpdatePassword 标志位来跳过更新数据密码的操作. 否则都要进行修改.

2. 组装数据

       组装好一个新的 userinfo (新的用户名或密码), 为更新数据库操作提供数据源, 此处更新密码成功的前提是原密码和数据库密码要保持一致, 而数据库中存储的是加密后的密码, 所以需要先拿着原密码和数据库中的密码去调用解密方法, 得到一个 boolean 类型的值, 再根据这个布尔值来判断是否要进行修改操作.

【注意】session 中的对象存储机制 >>

      由于我们是可以拿到当前用户的  session, 所以想要拿数据库中存储的密码, 我就会想着去 session 中拿到 userinfo, 再去拿到对应的密码, 这确实挺方便. 但是我在实现登录页面时, 登录成功后并将 session 存储 redis, 但是在返回数据给前端之前, 我执行了将密码置为空字符串这一操作, 因为密码如果通过网络传输返回给前端, 是不安全的. 

        <问题的出处>  正因为我的这一步置空字符串操作, 就会导致 session 中的密码也变成了空字符串. 这是为什么呢 ??

因为 session 的底层是用 concurrentHashMap 来保存数据的, 而 map 中并没有直接存储新的对象, 而是存储了对象的引用, 也就是 userinfo 的引用, 虽然我是在设置密码为空之前就将 userinfo 存储 session 了, 但是这也同样影响了 session 中的 password 了. 此时 session 中的 password 已经是空字符串了.

       再回到调用解密方法这一步, 我们就不能拿着原密码和 session 中的密码去调用解密码方法了, 而是需要拿着从 session 获取到的 userinfo 中的用户 id, 去查数据库得到一个新的 userinfo, 此时这个 userinfo 的密码才不为空, 才可以拿着它的 password 去和原密码去调用解密方法.

3. 修改数据库

        经过了第二步的组装数据, 第三步就变得简单了, 只需要使用 MP 进行修改操作即可, 但是在进行修改操作时, 修改后的用户名或密码最好设置在 updatewrapper 中, 然后只传一个 wrapper 对象. 如果将修改后的用户名或密码设置给 session 中的 userinfo, 然后再给 MP 传两个参数 (userinfo, wrapper), 那么有可能造成不必要的参数覆盖问题.

       另外就是修改完数据库之后, 要及时更新 session 中的用户名, 因为如果只修改了用户名, 不修改密码, 修改完成后会跳转博客列表页, 而博客列表页的用户身份信息都是从后端的 session 中来的, 如果不及时更新 session 的话, 那么在你下次重新登录之前, 用户名都不会变.

上述的 session 中的对象存储机制是参考这篇文章得出的结论  - 为何session中存入对象后,修改对象的属性值后并没有再次存入session,session中存放的对象也发生改变?

到此为止呢, 修改头像, 修改用户名或密码就全部实现完成了~


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

个人中心 - 实现修改用户头像、用户名或密码 的相关文章

  • 在 Spring Boot 中重新加载/刷新缓存

    我正在使用 Spring Boot 对于缓存 我使用 Ehcache 到目前为止一切正常 但现在我必须重新加载 刷新 那么我该如何执行此操作 以便我的应用程序不会出现任何停机时间 我在Spring Ehcache中尝试了很多方法 但它不起作
  • Criteria eager fetch-joined 集合以避免 n+1 选择

    假设 Item 和 Bid 是实体 一个 Item 有多个 Bid 它们被映射到休眠在典型的父子关系中
  • 在游戏框架中编写功能测试的正确方法

    在为基于 play1 2 4 的 web 应用程序编写功能测试时 我对如何正确编码感到有点困惑 困惑在于所涉及的事务边界 我在某处读到每个测试都有自己的事务 在我的应用程序中 用户可以登录并向购物车添加一些商品 然后他可以提供一个地址 以便
  • 如何向 OkHttp 请求拦截器添加标头?

    我将这个拦截器添加到我的 OkHttp 客户端 public class RequestTokenInterceptor implements Interceptor Override public Response intercept C
  • SimpleDateFormat 无法正确处理 DD

    我正在尝试获得这样的格式 2013 06 15 17 45 我在代码中执行以下操作 Date d new Date SimpleDateFormat ft new SimpleDateFormat YYYY MM DD HH mm Stri
  • ORMLite - join where 子句中的括号

    我想使用连接三个表QueryBuilder join and QueryBuilder joinor但我想在 where 子句中添加括号 如下所示 WHERE first table where AND second table where
  • 使用用户名进行 Java LDAP 身份验证

    好吧 这让我发疯 我正在尝试使用 Java 创建 LDAP 身份验证 如果我在 SECURITY PRINCIPAL 中使用我的名字和姓氏 一切都很好 这是我的代码 try Hashtable
  • Eclipse 内容协助无法在枚举常量参数列表中工作

    使用 eclipse 当我输入以下内容时 public enum Foo A Integer private final Integer integer private Foo Integer integer this integer in
  • Java 中的 TreeSet 与 C#.net 的等效项

    我有 Java 代码 其中包含TreeSet 我想将代码转换为 C 我可以使用哪个等效集合 如果没有 请提出替代方案 那将是系统 集合 通用 SortedSet
  • java模拟自定义对象

    public class MainClass public void makeCall CustomObject obj new CustomObject obj testMethod 我想进行单元测试makeCall 所以我必须嘲笑Cus
  • 在Tomcat中设置环境变量TESSDATA_PREFIX

    我们正在使用名为 Tess4J 的 Tesseract OCR Java 库 如果作为独立应用程序运行 它可以正常工作 它需要一个名为 TESSDATA PREFIX 的变量 其中包含 tessdata 配置和其他字符集相关文件 它也可以与
  • Java中的运算符重载和覆盖

    运算符重载和运算符重写有什么区别 它们在继承和控制台程序中是否相同 Java 不支持运算符重载和重写 检查以下引用自的描述 http java sun com docs white langenv Simple doc2 html http
  • 基于Java模式分割字符串

    您好 我有以下模式的日志文件 2014 03 06 03 21 45 432 ERROR mfs pool 3 thread 19 dispatcher StatusNotification Error processing notific
  • 如何在Android中使用资源

    一个人如何使用资产 我有这个代码 AssetManager assets getAssets InputStream stream assets open test txt 看起来它只能在 Activity 类中使 用 如果我尝试在另一个类
  • 未从线程接收位置数据

    我尝试使用计时器经常发送包含用户位置的短信 最初 我遇到了空指针异常 这是由于我犯了一个简单的错误 一旦解决了这个问题 一切似乎都运行良好 但是 它永远不会获取我的位置 因此 不断发送的文本显示 无法接收位置 我想问的是为什么它无法获取我的
  • 无法从 ViewPager 中的 Fragment 编辑 ActionBar 标题

    我有一个Activity它通过一个托管多个片段ViewPager 在活动的onCreate方法我使用以下代码来更改ActionBar title Toolbar toolbar findViewById R id toolbar setSu
  • JSF“总”变量类似于 JSTL 中的 c:set

    我不喜欢 JSF 但我需要用它来解决这个问题 我正在 纯 JSF 中工作 所以这就是我基本上需要的 但我不知道如何用 JSF 来实现它
  • 如何使用 Kafka 发送大消息(超过 15MB)?

    我发送字符串消息到Kafka V 0 8使用 Java Producer API 如果消息大小约为 15 MB 我会得到MessageSizeTooLargeException 我尝试过设置message max bytes到 40 MB
  • 丰富:数据表行跨度问题

    我需要创建一个 rich dataTable 甚至扩展 具有以下功能 我有一个公司类 其中包含产品对象的集合 我想展示下表 我仍然没有弄清楚如何使用子表执行此操作 在所有示例中 我发现子表具有与主表完全相同的列 据推测 我需要在前两列中使用
  • Java:如何检测(并更改?)System.console 的编码?

    我有一个在控制台上运行的程序 其变音符号和其他特殊字符在 Mac 上以 的形式输出 这是一个简单的测试程序 public static void main String args System out println h h System

随机推荐

  • 深度学习_调参经验

    面对一个图像分类问题 可以有以下步骤 1 建立一个简单的CNN模型 一方面能够快速地run一个模型 以了解这个任务的难度 卷积层1 卷积核大小3 3 卷积核移动步长1 卷积核个数64 池化大小2 2 池化步长2 池化类型为最大池化 激活函数
  • leetCode热题46-51 解题代码,调试代码和思路

    前言 本文属于特定的六道题目题解和调试代码 正所谓磨刀不误砍柴功 下面我做这几篇文档对于涉及的题型或者数据结构的分析都很有帮助 贴出来仅供参考 1 69 x 的平方根 Easy 2022 12 28 101 2 22 括号生成 Medium
  • JSP核心标签库

    1 一般标签 在JSTL中 一般标签主要用在输出 设置变量值和错误处理等 这些是JSTL中使用最多的标签 1 计算一个表达式的值 然后把计算的结果输出到当前的JspWriter对象 调用的结果和Servlet中out println 语句效
  • linux 删除指定文件夹包含指定字符串的文件会把所有子文件夹包含的都删除

    需求就是在linux服务器上面删除 指定文件夹里面所有包含 delete 内容的文件 并且所有此文件夹里面的子文件夹查出来也要删除掉 使用以下脚本可以进行实现 grep r l delete data xargs rm rf 脚本说明 gr
  • 机器学习-fp16相乘

    1位符号位 5位指数位 10位尾数位 共16位 内存占2个字节 具体fp16表示法可以参照 机器学习 fp16表示 运算步骤 检查操作数中是否有0 Inf NaN NaN a Nan Inf 0 Nan Inf 0 Nan Inf a In
  • UTSim:无人机空中交通集成、控制和通信的框架和模拟器

    计算机仿真资源的可用性有利于无人机的开发和在现实应用中的集成 因为它们降低了成本 风险 开发和测试时间 并提高了安全水平 一些研究人员为自己的定制特殊无人机和应用开发了自己的模拟环境 然而 使用多个无人机仿真环境很难建立可持续的研究 因为很
  • CSAPP第三版运行时打桩Segmentation fault

    CSAPP第三版7 13 3节提到了运行时打桩机制 它可以在运行时将程序中对共享库函数的调用进行截获 替换为执行自己的代码 这个机制基于动态链接器的LD PRELOAD环境变量 如果LD PRELOAD环境变量被设置为一个共享路径名的列表
  • docker搭建registry私有仓库(centos7)

    搭建环境 master节点 registry端 192 168 1 10 node节点 客户端 192 168 1 20 关闭防火墙和selinux master和node节点都要关闭 root master systemctl stop
  • 【夜莺监控方案】04-k8s集群监控(下)(kube-state-metrics+cadvisor+prometheus+n9e及FAQ)

    文章目录 前言 4 接入prometheus 5 接入n9e 5 1 手动接入 方法一 5 2 导入模板 方法二 6 FAQ 6 1 集群数据时常取不到 现象 解决 前言 相关文档如下 03 k8s集群监控 上 4 接入prometheus
  • 【Navicat11安装教程】

    1 下载安装包 网盘地址 链接 提取码 bbqp 下载之后会得到这样的一个文件夹 2 安装 点击navicat111 mysql cs x64 exe安装软件 安装完成后 将PatchNavicat exe文件复制到安装路径下 如图 操作完
  • idea 工程目录横向变纵向【亲测可用】

    idea 目录横向变纵向往上搜好多都没啥用 下面亲测可用三步走 1 删除项目文件夹下的 idea文件夹 横向时点击 project 然后在 idea 下右击 Delete 就好了 2 关闭IDEA 3 重新用IDEA工具打开项目 然后就 O
  • Android如何配置init.rc中的开机启动进程(service)

    开篇 为什么写这篇文章 先说下我自己的情况 我是个普通的学生 之前在学校一直做Android应用开发 找实习的时候也一直想找相关的工作 来到现在这家公司以后 由于业务调整 被领导安排去做底层开发 本来我对底层的东西一无所知 加上其实并不感兴
  • Python 函数是传值还是传引用

    传递参数的时候 python不允许程序员选择采用传值还是传引用 Python参数传递采用的肯定是 传对象引用 的方式 实际上 这种方式相当于传值和传引用的一种综合 如果函数收到的是一个可变对象 比如字典或者列表 的引用 就能修改对象的原始值
  • C++中char和int型变量的一点心得

    字符字面值一般是用一对单引号来表示 char类型一般就是用字符字面值来初始化 赋值 由于char类型的是单字节长度 当给char类型的变量用字符 字面值赋值时 当单引号里面的内容超过一个字节时 系统会自动截取一个字节的内容给char变量 忽
  • JVM-了解概念

    1 什么是JVM JVM是 java Virtual Machine java虚拟机 的缩写 JVM是作用于计算设备的规范 它是一个虚构出来的计算机 是通过在实际计算机上仿真模拟各种计算机功能来实现的 java虚拟机包括一套字节码指令集 一
  • 苏宁 11.11:仓库内多 AGV 协作的全局路径规划算法研究

    本文为 InfoQ x 苏宁 2018双十一 技术特别策划系列文章之一 1 背景 随着物联网和人工智能的发展 越来越多的任务渐渐的被机器人取代 机器人逐渐在发展中慢慢进入物流领域 智能叉车 AGV Automated Guided Vehi
  • ROS :发送一个目标位置,机器人自动规划路线,移动到该位置。

    使用 Action move base msgs MoveBaseAction move base在world中的目标 新建send goal cpp send goal cpp Created on Aug 10 2016 Author
  • minio 配置

    文章目录 资源访问 用户和权限 策略 用户 Service Accounts java 连接 minio k8s 部署 minio 资源访问 某些资源例如图片 需要可以直接访问 新建桶 上传一张图片上去 点击桶设置 设置 Access Po
  • 灰度共生矩阵的原理及实现(特征提取)-OpenCV

    最近在研究机器学习相关内容 后面会尽量花时间整理成一个系列的博客 然后朋友让我帮他实现一种基于SVR支持向量回归的图像质量评价方法 然而在文章的开头竟然发现 灰度共生矩阵这个陌生的家伙 于是便有此文 主要参考博客1 http blog cs
  • 个人中心 - 实现修改用户头像、用户名或密码

    目录 1 修改用户头像 1 1 获取原来的用户头像和用户名 1 2 实现保存头像 2 修改用户名或密码 1 修改用户头像 本文是针对之前的一篇项目博客 博客系统 做的一个扩展功能 1 1 获取原来的用户头像和用户名 想要修改头像 那么就得先