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

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(使用前将#替换为@)

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

  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 无法捆绑适用于 Mac 的 Java 应用程序 1.8

    我正在尝试将我的 Java 应用程序导出到 Mac 该应用程序基于编译器合规级别 1 7 我尝试了不同的方法来捆绑应用程序 1 日食 我可以用来在 Eclipse 上导出的最新 JVM 版本是 1 6 2 马文 看来Maven上也存在同样的
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • 如何修复 JNLP 应用程序中的“缺少代码库、权限和应用程序名称清单属性”?

    随着最近的 Java 更新 许多人都遇到了缺少 Java Web Start 应用程序的问题Codebase Permissions and Application name体现属性 尽管有资源可以帮助您完成此任务 但我找不到任何资源综合的

随机推荐

  • 深度学习_调参经验

    面对一个图像分类问题 可以有以下步骤 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 获取原来的用户头像和用户名 想要修改头像 那么就得先