当前位置: 首页 > news >正文

8. 实现业务功能--用户注册

目录

1. 顺序图

2. 参数要求

3. 接口规范

4. 创建扩展 Mapper.xml 

5. 修改 DAO 

6. 创建 Service 接口

7. 实现接口

8. 测试接口

9. 实现 Controller

9.1 密码加密处理

10. 实现前端界面


业务实现过程中主要的包和目录及主要功能:
  • model 包:实体对象
  • dao 包:数据库访问
  • services 包:业务处理相关的接口与实现,所有业务都在 Services 中实现
  • controller 包:提供 URL 映射,用来接收参数并做校验, 调用 Service 中的业务代码 ,返回执行结果
  • src/main/resources/mapper 目录:Mybaits 映射文件,配置数据库实体与类之间的映射关系
  • src/main/resources/static 目录:前端资源

那么我们再来看一下各个包之间的调用关系

  • Controller 包:主要用来接收用户的参数,并封装 Service 层需要使用的对象,最终为客户端响应结果
  • Service 包:处理业务逻辑,调用 dao 包完成数据的持久化。如果要执行多条数据库更新操作,那么就需要用事务管理

1. 顺序图

注意, 5 应该为根据用户名查询用户信息,即 selectByName(name)。

2. 参数要求

注册时,需要用户提交的参数列表:

参数名描述参数默认值条件
username用户名String必须
nickname昵称String与用户名相同必须
password密码String必须
passwordRepeat确认密码String必须,与密码相同

必须 即 需要进行非空校验,还需要进行两次密码输入校验。 

3. 接口规范

// 请求
POST /user/register HTTP/1.1Content-Type: application/x-www-form-urlencoded
username=user222&nickname=user222&password=123456&passwordRepeat=123456
// 响应
HTTP/1.1 200
Content-Type: application/json
{"code":0,"message":"成功","data":null}

接下来,就是实现 Service 层,具体通过以下步骤:

1. 在 Mapper.xml 中编写 SQL 语句
2. 在 Mapper.java 中定义方法
3. 定义 Service 接口
4. 实现 Service 接口
5. 单元测试
6. Controller 实现方法并对外提供的 API 接口
7. 测试 API 接口
8. 实现前端逻辑,完成前后端交互

4. 创建扩展 Mapper.xml 

写入操作:已经存在(自动生成的)不需要手动编写

根据用户名查询信息:

为了避免在自动生成时重复生成相同的语句,我们在 mapper 包下,新建一个 extension 包,将 UserMapper.xml 文件重新复制一份,并重命名为:UserExtMapper

注意: 

因为,命名相同的 xml 文件最终会被解析成一个大文件,里面定义的所有标签都可以相互调用。

接下来,我们先来查看一下此时数据库中的数据:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.UserMapper"><!--1. 注意 namespace 表⽰命名空间,要与 UserMapper.xml 中的 namespace 相同2. 统⼀⽤ com.example.forum.dao.UserMapper, 也就是UserMapper的完全限定名(包名+类名)3. 不同的映射⽂件指定了相同的namespace后,定义的所有⽤id或name标识的结果集映射都可以在不同的⽂件中共享
--><!--  根据用户名查询用户信息  --><select id="selectByName" parameterType="java.lang.String" resultMap="BaseResultMap">SELECT<include refid="Base_Column_List" />from t_user where username = #{username,jdbcType=VARCHAR}</select>
</mapper>

可以看到我们用来代替 * 的语句中,使用的标签已经进行了全列的定义:

5. 修改 DAO 

/**
* 根据用户名查询用户信息
* @param username 用户名
* @return
*/
User selectByName(String username);

6. 创建 Service 接口

在 demo 包下创建 services 包,在 services 包下创建 IUserService 接口。

接口的命名规则: I + 实现类的名字 + Service 

public interface IUserService {/*** 根据用户名查询用户信息* @param username 用户名* @return*/User selectByName(String username);/*** 创建普通用户* @param user 用户名* @return*/User createNormalUser(User user);
}

7. 实现接口

在 services 包下新建 impl 包,在 impl 包下新建类:UserServiceimpl 类,并实现 IUserService 接口:

 命名规则:实体类名 + Service + Impl

接下来 Alt + 回车 生成实现方法,并加入注解:

@Slf4j // 日志
@Service // 交给 Spring 管理
public class UserServiceImpl implements IUserService {@Overridepublic User selectByName(String username) {return null;}@Overridepublic User createNormalUser(User user) {return null;}
}

 在实现的过程中需要对每一个必传参数做非空校验,从而保证程序的健壮性

可以看到我们需要多次使用到非空校验的判断,因此我们可以将此处的语句抽取出来,放在一个公共的工具类中。在 demo 包下新建包 utils,在 utils 包下新建类 StringUtils:

public class StringUtils {/*** 校验指定的字符串是否为空* @param value 待校验的字符串* @return true 空 <br/> false 非空*/public static boolean isEmpty(String value){if(value == null || value.isEmpty()){return true;}return false;}
}

接下来继续完善我们的实现接口部分:

@Slf4j // 日志
@Service // 交给 Spring 管理
public class UserServiceImpl implements IUserService {@Resourceprivate UserMapper userMapper;@Overridepublic User selectByName(String username) {// 非空校验if(StringUtils.isEmpty(username)){// 打印日志log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());// 抛出异常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));}// 根据用户名查询用户信息User user = userMapper.selectByName(username);// 返回结果return user;}@Overridepublic User createNormalUser(User user) {return null;}
}

接下来我们实现 createNormalUser 方法:

@Slf4j // 日志
@Service // 交给 Spring 管理
public class UserServiceImpl implements IUserService {@Resourceprivate UserMapper userMapper;@Overridepublic User selectByName(String username) {// 非空校验if(StringUtils.isEmpty(username)){// 打印日志log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());// 抛出异常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));}// 根据用户名查询用户信息User user = userMapper.selectByName(username);// 返回结果return user;}@Overridepublic void createNormalUser(User user) {// 非空校验if(user == null || StringUtils.isEmpty(user.getUsername())|| StringUtils.isEmpty(user.getNickname())|| StringUtils.isEmpty(user.getPassword())|| StringUtils.isEmpty(user.getSalt())){// 打印日志log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());// 抛出异常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));}// 校验用户是否存在User existUser = selectByName(user.getUsername());if(existUser != null){// 打印日志log.warn(ResultCode.FAILED_USER_EXISTS.toString() + "username = " + user.getUsername());// 抛出异常,用户已存在throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));}// 为属性设置默认值// 性别 0女 1男 2保密if(user.getGender() != null){if(user.getGender() < 0 || user.getGender() > 2){user.setGender((byte)2);}}else{user.setGender((byte)2);}// 发帖数user.setArticleCount(0);// 是否管理员user.setIsAdmin((byte)0);// 状态user.setState((byte)0);// 时间Date date = new Date();user.setCreateTime(date); // 创建时间user.setUpdateTime(date); // 更新时间// 写入数据库int row = userMapper.insertSelective(user);if(row != 1){// 打印日志log.warn(ResultCode.FAILED_CREATE.toString() + "注册用户失败,username = " + user.getUsername());// 抛出异常,用户已存在throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));}}
}

8. 测试接口

在 UserServiceImpl 类中右键生成测试方法:

加上 @SpringBootTest 注解:

@SpringBootTest
class UserServiceImplTest {@Resourceprivate IUserService userService;@Resourceprivate ObjectMapper objectMapper;  // JSON 对象@Testvoid selectByName() throws JsonProcessingException {// 调用 Service 查询用户信息User user = userService.selectByName("bitboy");System.out.println(objectMapper.writeValueAsString(user));System.out.println("========================================");user= userService.selectByName("bitboy111");System.out.println(objectMapper.writeValueAsString(user));System.out.println("========================================");user = userService.selectByName(null);System.out.println(objectMapper.writeValueAsString(user));}@Testvoid createNormalUser() {}
}

查询结果如下:

与数据库中的数据相符合,因此测试成功。

接下来添加 createNormalUser 的测试:

@SpringBootTest
class UserServiceImplTest {@Resourceprivate IUserService userService;@Resourceprivate ObjectMapper objectMapper;  // JSON 对象@Testvoid selectByName() throws JsonProcessingException {// 调用 Service 查询用户信息User user = userService.selectByName("bitboy");System.out.println(objectMapper.writeValueAsString(user));System.out.println("========================================");user= userService.selectByName("bitboy111");System.out.println(objectMapper.writeValueAsString(user));System.out.println("========================================");
//        user = userService.selectByName(null);
//        System.out.println(objectMapper.writeValueAsString(user));}@Testvoid createNormalUser() {// 构造用户User user = new User();user.setUsername("TestUser1");user.setNickname("单元测试用户1");user.setPassword("123456");user.setSalt("123456");// 调用 ServiceuserService.createNormalUser((user));System.out.println("注册成功");System.out.println("========================");user.setUsername("bitboy");// 调用 ServiceuserService.createNormalUser((user));System.out.println("注册成功");}
}

运行结果如下图所示:

测试成功。

9. 实现 Controller

在 controller 包下新建 UserController 类:

9.1 密码加密处理

由于在存储用户的密码时,不能直接存储明文,否则会泄露账户信息,因此需要通过盐进行加密处理,最终将盐和密文(明文密码+ 扰动字符串(盐))存储在数据库中。

盐 -> 随机字符

MD5(MD5(明文密码) + SALT)= 密码对应的密文

新建 UUIDUtils 类:

public class UUIDUtils {/*** 生成一个标准的36字符的UUID** @return*/public static String UUID_36() {return UUID.randomUUID().toString();}/*** 生成一个32字符的UUID** @return*/public static String UUID_32() {return UUID.randomUUID().toString().replace("-", "");}
}

在 ForumApplicationTests 类中添加测试方法:

@Testvoid testUUID(){System.out.println(UUIDUtils.UUID_36());System.out.println(UUIDUtils.UUID_32());}

结果如下图所示:

在 pom.xml 中添加依赖:

<!-- 编码解码加密⼯具包-->
<dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId>
</dependency>

在 utils 包下新建 MD5Utils 类:

import org.apache.commons.codec.digest.DigestUtils;;public class MD5Utils {/*** 普通MD5加密* @param str 原始字符串* @return ⼀次MD5加密后的密⽂*/public static String md5 (String str) {return DigestUtils.md5Hex(str);}/*** 原始字符串与Key组合进⾏⼀次MD5加密* @param str 原始字符串* @param key* @return 组合字符串⼀次MD5加密后的密⽂*/public static String md5 (String str, String key) {return DigestUtils.md5Hex(str + key);}/*** 原始字符串加密后与扰动字符串组合再进⾏⼀次MD5加密* @param str 原始字符串* @param salt 扰动字符串* @return 加密后的密⽂*/public static String md5Salt (String str, String salt) {return DigestUtils.md5Hex(DigestUtils.md5Hex(str) + salt);}/*** 校验原⽂与盐加密后是否与传⼊的密⽂相同* @param original 原字符串* @param salt 扰动字符串* @param ciphertext 密⽂* @return true 相同, false 不同*/public static boolean verifyOriginalAndCiphertext (String original, String salt, String ciphertext) {String md5text = md5Salt(original, salt);if (md5text.equalsIgnoreCase(ciphertext)) {return true;}return false;}
}

继续在 UserController 类中编写代码: 

@Api(tags = "用户接口")
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate IUserService userService;@ApiOperation("用户注册")@PostMapping("/register")public AppResult register(@ApiParam("用户名") @RequestParam("username") @NonNull String username,@ApiParam("昵称") @RequestParam("nickname") @NonNull String nickname,@ApiParam("密码") @RequestParam("password") @NonNull String password,@ApiParam("确认密码") @RequestParam("passwordRepeat") @NonNull String passwordRepeat){// 校验密码是否一致if (!password.equals(passwordRepeat)) {// 返回错误信息return AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);}// 构造对象User user = new User();user.setUsername(username); // 用户名user.setNickname(nickname); // 昵称// 处理密码// 1.生成盐String salt = UUIDUtils.UUID_32();// 2.生成密码的密文String encryptPassword = MD5Utils.md5Salt(password, salt);// 3 设置密码和盐user.setPassword(encryptPassword);user.setSalt(salt);// 3. 调⽤ServiceuserService.createNormalUser(user);// 4. 返回结果return AppResult.success("注册成功");}
}

运行启动类 ForumApplication:

打开:http://127.0.0.1:58080/swagger-ui/index.html

接下来进行密码测试:

测试成功:

继续测试用户名:

测试成功:

继续测试正确的输入:

测试成功:

查看数据库中的数据:

 可以看到数据库中显示的密码已经进行了加密处理。

10. 实现前端界面

完成表单校验工作后,需要构造要提交的数据:

  1. 通过选择器找到需要提交的标签
  2. 获取标签中的值,并封装成JS对象
    1. 前后端交互时定义的参数列表:参数名=对象的属性 参数值=标签中的值(用户输入的值)

完整的前端代码可以参考:forum: 论坛项目 - Gitee.com

接下来我们打开注册界面,输入已有的用户名,可以看到提示框弹出: 

接下来,我们在 html 文件中,自定义弹出的提示框的样式。

 $.toast({heading: '警告',text: respData.message,icon: 'Warning'});

 停止运行启动类,重新进行注册,可以看到:

接下来,我们正确的进行注册: 

可以看到通过前端界面进行注册后,数据库中正确增加了一条数据。 

并且注册成功后直接跳转至了登录界面:


 用户注册的基本功能已经实现,在下篇文章中,我们将实现用户登录功能。

相关文章:

8. 实现业务功能--用户注册

目录 1. 顺序图 2. 参数要求 3. 接口规范 4. 创建扩展 Mapper.xml 5. 修改 DAO 6. 创建 Service 接口 7. 实现接口 8. 测试接口 9. 实现 Controller 9.1 密码加密处理 10. 实现前端界面 业务实现过程中主要的包和目录及主要功能&#xff1a; model 包&#xff1a;实体对象 d…...

深入浅出Pytorch函数——torch.nn.init.eye_

分类目录&#xff1a;《深入浅出Pytorch函数》总目录 相关文章&#xff1a; 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...

版本控制工具Git集成IDEA的学习笔记(第一篇Gitee)

目录 一、Gitee的使用 1、注册网站会员 2、用户中心 3、创建远程仓库 4、配置SSH免密登录 二、集成IDEA&#xff0c;Git项目搭建 1、本地仓库搭建 1&#xff09;创建一个新项目 2&#xff09;打开终端&#xff0c;在当前目录新建一个Git代码库 3&#xff09;忽略文件 …...

【链表】 61. 旋转链表

61. 旋转链表 解题思路 首先计算出链表长度将链表长度进行取余遍历链表 对链表进行分割 得到两个子链表重新连接两个链表比如1 2 3 4 5 k 2 进行分割得到 1 2 3 和 4 5两个子链表 /*** Definition for singly-linked list.* public class ListNode {* int val;* Lis…...

深入浅出Pytorch函数——torch.nn.init.kaiming_uniform_

分类目录&#xff1a;《深入浅出Pytorch函数》总目录 相关文章&#xff1a; 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...

查询Oracle和MySQL数据库中当前所有连接信息

查询Oracle当前所有连接信息&#xff1a; SELECTs.sid AS 会话ID,s.serial# AS 序列号,s.username AS 用户名,s.osuser AS 操作系统用户,s.machine AS 客户端机器,s.program AS 客户端程序,s.status AS 会话状态,s.sql_id AS 正在执行的SQL_ID,t.sql_text AS 正在执行的SQL文本…...

Android glide框架及框架涉及到的设计模式

目录 原文链接Android glide框架 简单使用介绍Glide 框架整体结构设计Glide 框架的优点基本使用&#xff1a;Glide占位符 Android glide框架涉及到的设计模式 原文链接 Android glide框架 简单使用介绍 Glide&#xff1a;快速高效的Android图片加载库&#xff0c;可以自动加载…...

使用yolov5进行安全帽检测填坑指南

参考项目 c​​​​​​​​​​​​​​GitHub - PeterH0323/Smart_Construction: Base on YOLOv5 Head Person Helmet Detection on Construction Sites&#xff0c;基于目标检测工地安全帽和禁入危险区域识别系统&#xff0c;&#x1f680;&#x1f606;附 YOLOv5 训练自己的…...

【BASH】回顾与知识点梳理(三十二)

【BASH】回顾与知识点梳理 三十二 三十二. SELinux 初探32.1 什么是 SELinux当初设计的目标&#xff1a;避免资源的误用传统的文件权限与账号关系&#xff1a;自主式访问控制, DAC以政策规则订定特定进程读取特定文件&#xff1a;委任式访问控制, MAC 32.2 SELinux 的运作模式安…...

vscode远程调试PHP代码

目录 一、准备工作 二、ssh连接和xdebug配置 1.ssh连接 2.xdebug配置 三、xdebug调试&#xff0c;访问 一、准备工作 1.安装vscode里面的两个扩展 2.安装对应PHP版本的xdebug 去xdebug官方&#xff0c;复制自己的phpinfo源码到方框里&#xff0c;再点击Analyse Xdebug: …...

flink1.17 实现 udf scalarFunctoin get_json_object 支持 非标准化json

特色 相比官方的json_value,该函数支持非标准化json,比如v是个object,但是非标准json会外套一层引号,内部有反引号. eg: {"kkkk2": "{\"kkkk1\":\"vvvvvvv\"}" } 支持value为 100L 这种java格式的bigint. {"k":999L…...

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)九:自定义组件封装下

一、本章内容 续上一张,本章实现一些自定义组件的封装,包括文件上传组件封装、级联选择组件封装、富文本组件封装等。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览 三、开发视频 基于VUE3+Layui从头搭建通用后台管...

设计模式详解-装饰器模式

类型&#xff1a;结构型模式 实现原理&#xff1a;装饰器模式通过将对象包装在装饰器类中&#xff0c;并在保持类方法签名完整性的前提下&#xff0c;提供额外功能 作用&#xff1a;动态地给一个对象添加一些额外的职责。增加功能方面&#xff0c;装饰器模式比生成子类更灵活…...

Android5:活动生命周期

创建项目Stopwatch activity_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_w…...

第2章 数据结构和算法概述

2.3线性结构和非线性结构 数据结构包括: 线性结构和非线性结构 2.3.1线性结构 线性结构作为最常用的数据结构&#xff0c;其特点是数据元素之间存在一对一的线性关系线性结构有两种不同的存储结构&#xff0c;即顺序存储结构(数组)和链式存储结构(链表)。顺序存储的线性表称…...

WPF国际化的实现方法(WpfExtensions.Xaml)

https://blog.csdn.net/eyupaopao/article/details/120090431 resx资源文件实现 resx资源文件&#xff0c;实现的过程比第一种复杂&#xff0c;但resx文件本身编辑比较简单&#xff0c;维护起来比较方便。需要用到的框架&#xff1a;WpfExtensions.Xaml 为每种语言添加.resx资…...

【Linux】—— 进程程序替换

目录 序言 &#xff08;一&#xff09;替换原理 1、进程角度——见见猪跑 1️⃣ 认识 execl 函数 2、程序角度——看图理解 &#xff08;二&#xff09;替换函数 1、命名理解 2、函数理解 1️⃣execlp 2️⃣execv 3️⃣execvp 4️⃣execle 5️⃣execve 6️⃣execve…...

idea创建javaweb项目,jboss下没有web application

看看下图这个地方有没有web application...

广东灯具3D扫描抄数建模服务3D测绘出图纸三维逆向设计-CASAIM

灯具三维逆向建模是一种将实际物体转换为数字模型的过程。通过逆向工程技术&#xff0c;可以将现有的灯具进行3D扫描&#xff0c;然后利用专业的逆向设计软件将其转换为准确的三维模型。 以下是CASAIM实施灯具三维逆向建模的一般步骤图&#xff1a; 1. 扫描&#xff1a;三维扫…...

Nginx反向代理-负载均衡、webshell实践

目录 1.nginx反向代理-负载均衡 1&#xff09;搭建web项目 2&#xff09;修改 nginx.conf的配置 2.webshell 实践 1&#xff09;异或操作绕过 2&#xff09;取反绕过 3&#xff09;php语法绕过 1.nginx反向代理-负载均衡 1&#xff09;搭建web项目 首先通过SpringBoo…...

第六阶|见道明心的笔墨(上)从书法之美到生活之美——林曦老师的线上直播书法课

如果你有需要&#xff0c;可以找我的&#xff0c;我这边有老师的所有课程 如果你有需要&#xff0c;可以找我的&#xff0c;我这边有老师的所有课程...

nbcio-boot从3.0升级到3.1的出现用户管理与数据字典bug

升级后出现 系统管理里的用户管理出现下面问题 2023-08-17 09:44:38.902 [http-nio-8080-exec-4] [1;31mERROR[0;39m [36mo.jeecg.common.exception.JeecgBootExceptionHandler:69[0;39m - java.lang.String cannot be cast to java.lang.Long java.lang.ClassCastException:…...

Curson 编辑器

Curson 汉化与vacode一样 Curson 自带chat功能 1、快捷键ctrlk(代码中编辑) 2、快捷键ctrll 右侧打开窗口...

Shell编程学习之函数的应用

Shell编程中的函数&#xff1a;伪代码表示&#xff1a; function 函数名(){函数体}注意事项&#xff1a; 1.函数无参数&#xff1b; 2.函数无返回值类型&#xff1b; 3.function可以不写&#xff1b; 4.函数不被调用&#xff0c;就不会执行&#xff1b; 5.函数名不能使用…...

Fork/Join框架

是什么 Fork/Join框架是Java 7提供的一个用于并行执行任务的框架&#xff0c;是一个把大任务分割成若干个小任务&#xff0c;最终汇总每个小任务结果后得到大任务结果的框架。 Fork: 把一个大任务切分为若干子任务并行的执行 Join: 合并这些子任务的执行结果&#xff0c;最后…...

LeetCode_字符串_中等_468.验证 IP 地址

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给定一个字符串 queryIP。如果是有效的 IPv4 地址&#xff0c;返回 “IPv4” &#xff1b;如果是有效的 IPv6 地址&#xff0c;返回 “IPv6” &#xff1b;如果不是上述类型的 IP 地址&#xff0c;返回 “Nei…...

ABAP Der Open SQL command is too big.

ABAP Der Open SQL command is too big. DBSQL_STMNT_TOO_LARGE CX_SY_OPEN_SQL_DB 应该是选择条件中 维护的条件值条数太多了...

QChart类用来 管理 图表的:数据序列(series)、图例(legend)和坐标轴(axis)

QChart类用来 管理 图表的&#xff1a;数据序列&#xff08;series&#xff09;、图例&#xff08;legend&#xff09;和坐标轴&#xff08;axis&#xff09; 1、数据序列类 继承关系 2、坐标轴类 的继承关系 3、图例类 什么是图例&#xff1f; 图例&#xff1a;是集中于地图…...

Servlet+JDBC实战开发书店项目讲解第10篇:在线客服功能实现

在线客服功能实现 实现思路 要实现在线客服功能&#xff0c;您可以考虑以下步骤&#xff1a; 创建一个用于存储客户消息和回复的数据库表。您可以使用JDBC连接到数据库&#xff0c;并使用SQL语句创建表格。 在您的Servlet中&#xff0c;创建一个用于处理客户消息和回复的POS…...

CVE-2023-21292 AMS框架层高危漏洞分析

文章目录 前言漏洞细节故事起源漏洞利用漏洞修复 总结 前言 本周在分析 Google 官方发布的 Android 2023 年8 月安全公告 涉及的漏洞补丁的时候&#xff0c;遇到一个有意思的漏洞&#xff1a;CVE-2023-21292。 之所以说它有意思是因为这个漏洞早在去年年底就在某平台上被国外…...

cuda、cuDNN、深度学习框架、pytorch、tentsorflow、keras这些概念之间的关系

当讨论CUDA、cuDNN、深度学习框架、pytorch、tensorflow、keras这些概念的时候&#xff0c;我们讨论的是与GPU加速深度学习相关的技术和工具。 CUDA&#xff08;Compute Unified Device Architecture&#xff09;&#xff1a; CUDA是由NVIDIA开发的一种并行计算平台和编程模型&…...

第二讲:BeanFactory的实现

BeanFactory的实现 1. 环境准备2. 初始化DefaultListableBeanFactory3. 手动注册BeanDefinition4. 手动添加后置处理器5. 获取被依赖注入的Bean对象6. 让所有的单例bean初始化时加载7. 总结 Spring 的发展历史较为悠久&#xff0c;因此很多资料还在讲解它较旧的实现&#xff0c…...

vue2+Spring Boot2.7 大文件分片上传

之前我们文章 手把手带大家实现 vue2Spring Boot2.7 文件上传功能 将了上传文件 但如果文件很大 就不太好处理了 按正常情况甚至因为超量而报错 这里 我弄了个足够大的文件 我们先搭建 Spring Boot2.7 环境 首先 application.yml 代码编写如下 server:port: 80 upload:path:…...

Vite更新依赖缓存失败,强制更新依赖缓存

使用vitets开发一段时间了&#xff0c;感觉并不是想象中的好用&#xff0c;特别是出现些稀奇古怪的问题不好解决&#xff0c;比如下面这个问题 上午9:50:08 [vite] error while updating dependencies: Error: ENOENT: no such file or directory, open E:/workspace-dir/node…...

Linux命令200例:tail用来显示文件的末尾内容(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…...

【Unity每日一记】进行发射,位置相关的方法总结

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…...

MISRA 2012学习笔记(3)-Rules 8.4-8.7

文章目录 Rules8.4 字符集和词汇约定(Character sets and lexical conventions)Rule 4.1 八进制和十六进制转译序列应有明确的终止识别标识Rule 4.2 禁止使用三字母词(trigraphs) 8.5 标识符(Identifiers)Rule 5.1 外部标识符不得重名Rule 5.2 同范围和命名空间内的标识符不得重…...

centos7组件搭建

Linux&#xff08;包括centos&#xff09; 如何查看服务器内存、CPU su - root 切换用户 centos 密码 空格 https://blog.csdn.net/weixin_45277161/article/details/131524555 CentOS 7 安装 Docker 的详细步骤 https://blog.csdn.net/qq_39997939/article/details/13100…...

webpack5和webpack4的一些区别

自动清除打包目录 webpack4 // bash npm i clean-webpack-plugin -D //webpack.config.js const {CleanWebpackPlugin} require(clean-webpack-plugin); module.exports {plugins: [new CleanWebpackPlugin()} } webpack5 module.exports {output: {clean: true} } topLevel…...

攻防世界-fileclude

原题 解题思路 直接展示源码了&#xff0c;flag.php应该存放了flag&#xff0c;在file1与file2都不为空且file2是“hello ctf”时file1将被导入。接下来做法很明显&#xff0c;让file为flag.php&#xff0c;file2为“hello ctf”。“?file1php://filter/readconvert.base64-en…...

深度学习的“前世今生”

1、“感知机”的诞生 20世纪50年代&#xff0c;人工智能派生出了这样两个学派&#xff0c;分别是“符号学派”及“连接学派”。前者的领军学者有Marvin Minsky及John McCarthy&#xff0c;后者则是由Frank Rosenblatt所领导。 “符号学派”的人相信对机器从头编程&#xff0c…...

第一百一十九回 如何通过蓝牙设备读写数据

文章目录 概念介绍实现方法示例代码经验总结我们在上一章回中介绍了如何获取蓝牙状态相关的内容,本章回中将介绍 如何通过蓝牙设备读写数据。闲话休提,让我们一起Talk Flutter吧。 概念介绍 通过蓝牙设备读写数据有两种方法: 一种是读写Characteristics;一种是读写Descri…...

linux:Temporary failure in name resolutionCouldn’t resolve host

所有域名无法正常解析。 ping www.baidu.com 等域名提示 Temporary failure in name resolution错误。 rootlocalhost:~# ping www.baidu.com ping: www.baidu.com: Temporary failure in name resolution rootlocalhost:~# 一、ubuntu/debian&#xff08;emporary failure i…...

C 语言的 sprintf() 函数

<stdio.h> 原型: int sprintf(char *str, const char *format, …) 发送格式化输出到 str 所指向的字符串。 参数 str – 这是指向一个字符数组的指针&#xff0c;该数组存储了 C 字符串。 format – 这是字符串&#xff0c;包含了要被写入到字符串 str 的文本。它…...

李沐pytorch学习-卷积网络及其实现

一、卷积概述 1.1 基本定义 卷积计算过程如图1所示&#xff0c;即输入矩阵和核函数&#xff08;filter&#xff09;对应的位置相乘&#xff0c;然后相加得到输出对应位置的数。 图1. 卷积计算过程 该过程可以形象地从图2中展现。 图2. 二维卷积示意图 1.2 实现互相关运算的代…...

记录:win10物理机ping不通虚拟机上的docker子网(已解决)

【说明】 windows10&#xff1a;已关闭防火墙 linux发行版本&#xff1a;centos7.9&#xff08;已禁用SElinux、已关闭防火墙&#xff09; 虚拟机软件&#xff1a;VMware Workstation 17 虚拟机网络模式&#xff1a;NAT模式 docker版本&#xff1a;20.4.5 docker网络模式…...

深入浅出Pytorch函数——torch.nn.init.kaiming_normal_

分类目录&#xff1a;《深入浅出Pytorch函数》总目录 相关文章&#xff1a; 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...

D. Anton and School - 2

范德蒙德恒等式 考虑统计每一个右括号位置的贡献&#xff0c;也就是每个右括号作为右边起点的贡献 其中i0的时候&#xff0c;r-1<r-0,故i0时贡献为0&#xff0c;直接套用恒等式不会有影响 #include <bits/stdc.h> using namespace std; typedef long long int ll; # d…...

xcode把包打到高版本的iPhone里

打开xcode CTRLb build工程&#xff0c;build成功 把手机连到mac&#xff0c;在xcode选项卡里面的window里面选中device and simulator 打开对应的手机的页面 然后在工程目录下build成功过后有一个product的文件夹里面&#xff0c;直接把app拖到对应的手机的窗口就可以不用…...

PMP项目管理考试小结

一、初步了解 每年有多次考试的机会&#xff0c;大概每三-四个月有一次考试机会&#xff0c;我下面分享的是我考试&#xff1a; 考试时间&#xff1a;8月19日 上午9:00-12:50 考试地点&#xff1a;北京市丰台区首都经济贸易大学&#xff08;城市不一样考点不一样&#xff09; …...