【SpringBoot】 黑马大事件笔记-day2

目录

用户部分

实体类属性的参数校验

更新用户密码

文章部分

规定josn日期输出格式

分组校验


上期回顾:【SpringBoot】 黑马大事件笔记-day1

用户部分


实体类属性的参数校验

对应的接口文档:

基本信息

请求路径:/user/update

请求方式:PUT

接口描述:该接口用于更新已登录用户的基本信息(除头像和密码)

请求参数

请求参数格式:application/json

请求参数说明:

请求数据样例:

{
"id":5,
"username":"wangba",
"nickname":"wb",
"email":"wb@itcast.cn"
}

响应数据

响应数据类型:application/json

响应参数说明:

响应数据样例:

{
"code": 0,
"message": "操作成功",
"data": null
}

        这种其实比较简单,就是底层的增删查改;明确接口文档的需求:username 不是必传项,而其他属性必须要传。而且传的属性值需要进行校验,确保数据的正确性。比如邮箱的格式需要规范,否则发不了短信找回账号。其次修改日期需要进行更新。

Contorller

    @RequestMapping("/update")public Result update(@RequestBody User user) {userService.update(user);return Result.success();}

Service

        我们可以使用 LocalDateTime.now() 方法来记录当前系统时间,这样用户信息的更新时间便有了。

    @Overridepublic void update(Category category) {category.setUpdateTime(LocalDateTime.now());categoryMapper.update(category);}

 Mapper

    <update id="update">UPDATE user SET nickname=#{nickname},email=#{email},update_time=#{updateTime} where id=#{id}</update>

        我们发现参数没有进行校验,容易导致一些错误:用户名有奇怪字符以及邮箱不正确导致发送不了验证码。

         所以我们要对参数进行校验:实体类的成员变量上添加注解

Pojo

@Data
@AllArgsConstructor
@NoArgsConstructor
public class  User {@NotNullprivate Integer id;//主键IDprivate String username;//用户名@JsonIgnore private String password;//密码@NotEmpty@Pattern(regexp = "^\\S{1,10}$")private String nickname;//昵称@NotEmpty@Emailprivate String email;//邮箱private String userPic;//用户头像地址private LocalDateTime createTime;//创建时间private LocalDateTime updateTime;//更新时间
}

        对实体类的属性添加注解,可以起到一定的约束作用:

注解作用
@NotNull不能为 null,但可以为 empty,一般用在 Integer 类型的基本数据类型的非空校验上
@NotEmpty不能为 null,且长度必须大于 0,一般用在集合类上或者数组上
@Email用于验证字符串是否符合电子邮件的格式,一般应用于 String 类的字段上
@Pattern被注解的元素必须符合给定的正则表达式,一般用来规定该属性的长度区间

注意:要使这些注解生效还有一个条件,就是在控制层传入参数的这里加上 @Validated 注解

    @RequestMapping("/update")public Result update(@RequestBody @Validated User user) {userService.update(user);return Result.success();}

        这样当我们重新运行项目时,就会抛出校验失败的异常。 

更新用户密码

对应的接口文档:

基本信息

请求路径:/user/updatePwd

请求方式:PATCH

接口描述:该接口用于更新已登录用户的密码

请求参数

请求参数格式:application/json

请求参数说明:

请求数据样例:

{
"old_pwd":"123456",
"new_pwd":"234567",
"re_pwd":"234567"
}

根据接口文档的说,我们可以知道修改密码需要三个属性:原密码、新密码、确认密码。

所以我们后端需要用 Map 来接收参数;为了保证密码的规范还需要对其进行校验:

密码的长度是否合法,有没有缺少参数
输入的原密码是否与数据库中的匹配
新密码与确认密码是否一致

只有满足以上条件,密码才能修改成功。

Controller

@PatchMapping("/updatePwd")public Result updatePwd(@RequestBody Map<String,String> params){// 校验参数String oldPwd = params.get("old_pwd");String newPwd = params.get("new_pwd");String rePwd = params.get("re_pwd");if(!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)) {return Result.error("缺少必要参数");}// 判断原密码Map<String,Object> map =  ThreadLocalUtil.get();String username = (String) map.get("username");User LoginUser =   userService.findByUserName(username);if(!Md5Util.getMD5String(oldPwd).equals(LoginUser.getPassword())) {return Result.error("原密码填写不正确");}// 修改密码和确认密码是否一样if(!newPwd.equals(rePwd)) {return Result.error("两次填写的密码不一致");}// 调用Service完成密码更新userService.updatePwd(newPwd);return Result.success();}

        由于在数据库中的密码是经过 Md5Util 加密的,所以比较时需要将输入原密码通过 Md5Util 转化后在比较。

Serivce

    @Overridepublic void updatePwd(String newPwd) {Map<String,Object> map = ThreadLocalUtil.get();Integer id = (Integer) map.get("id");userMapper.updatePwd(Md5Util.getMD5String(newPwd),id);}

        由于需要修改密码,首先要获取用户的信息;之前在 ThreadLocal 存放的用户信息 id 此时就就可以直接获取。

Mapper

        别忘记每次更新数据库数据都需要更新修改时间。

     <update id="updatePwd">UPDATE user SET password=#{newPwd},update_time=now() WHERE id=#{id}</update>

文章部分


规定josn日期输出格式

@JsonFormat 是在 Jackson 中定义的一个注解,是一个时间格式化注解。此注解用于属性上,作用是把 Date 类型的数据转化成为我们想要的格式。

    @JsonFormat(pattern = "yyyy-mm-dd HH:mm:ss")private LocalDateTime createTime;//创建时间@JsonFormat(pattern = "yyyy-mm-dd HH:mm:ss")private LocalDateTime updateTime;//更新时间

 

分组校验

需求

        我们经常会碰到这样的一个场景: 

Controller

    @PostMappingpublic Result add(@RequestBody @Validated Category category) {categoryService.add(category);return Result.success();}@PutMappingpublic Result update(@RequestBody @Validated Category category) {categoryService.update(category);return Result.success();}

Pojo

    @NotNullprivate Integer id;//主键ID

        更新的时候某些字段为必填(比如id), 新增的时候非必填:

Service

    @Overridepublic void add(Category category) {// 补充属性category.setCreateTime(LocalDateTime.now());category.setUpdateTime(LocalDateTime.now());// 获取用户idMap<String,Object> map = ThreadLocalUtil.get();Integer id = (Integer) map.get("id");category.setCreateUser(id);categoryMapper.add(category);}@Overridepublic void update(Category category) {category.setUpdateTime(LocalDateTime.now());categoryMapper.update(category);}

Mapper

    <insert id="add">INSERT INTO category(category_name, category_alias, create_user, create_time, update_time)VALUES (#{categoryName},#{categoryAlias},#{createUser},#{createTime},#{updateTime})</insert><update id="update">UPDATE category SET category_name=#{categoryName},category_alias=#{categoryAlias},update_time=#{updateTime}WHERE id=#{id}</update>

 

        新增的时候只需获取 ThreadLocal 中的用户 id 进行有效的插入即可,Mapper 并不涉及 id 的操作,所以获取请求时不需要传入 id;更新的时候 Mapper 需要 id 进行文章信息的定位,所以获取请求时需要传入 id。但是我们在 Pojo 给 id 属性加了 @NotNull 注解,表示不能为空;所以新增在获取对象请求的时候必须传入 id 否则就会抛出异常。

        如何解决这种问题呢?Validator 校验框架提供了分组校验,可以帮助我们快速的实现这样的需求。简单来说就是,新增时使用新增校验规则,更新时使用更新校验规则。

分组校验
        把校验项进行归类分组,在完成不同的功能的时候,校验指定组中的校验项。

步骤:

定义分组
定义校验项时指定归属的分组
校验时指定要校验的分组

定义分组:

我们以在 Pojo 实体类中定义两个接口,说明分了 Add、Update 两个组。

public class Category {public interface Add {}public interface Update {}
}

定义校验项时指定归属的分组:

public class Category {@NotNull(groups = Update.class)private Integer id;@NotEmpty(groups= {Add.class,Update.class})private String categoryName;@NotEmpty(groups= {Add.class,Update.class})private String categoryAlias;public interface Add {}public interface Update {}
}

校验时指定要校验的分组:

    @PostMappingpublic Result addCategory(@RequestBody @Validated(Category.Add.class) Category category) {categoryService.add(category);return Result.success();}@PutMappingpublic Result update(@RequestBody @Validated(Category.Update.class) Category category) {categoryService.update(category);return Result.success();}

        这样新增时就不需要传入 id 了。

结合 @Validated 源码:我们来看一下

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {Class<?>[] value() default {};
}

        例如:@Validated 注解中增加了 Category.Add.class 参数,表示对于定义了分组校验的字段使用 Add 校验规则,其他字段使用默认规则。

这样就又出现了另一个问题:如果同一个校验项属于多个分组的话,就需要在 groups= {} 中传入多个参数;这样我们就可以使用 @Validated 默认分组来优化这个问题。

举个例子:

        如果说某个校验项没有指定分组,默认属于 Default 分组。分组之间可以继承,A extends B 那么 A 中拥有 B 中所有的校验项。

public class Category {@NotNull(groups = Update.class)private Integer id;@NotEmptyprivate String categoryName;@NotEmptyprivate String categoryAlias;public interface Add extends Default {}public interface Update extends Default{}
}

        所以 @NotEmpty 就相当于 groups= {Add.class,Update.class},而 @NotNull(groups = Update.class) 指定了校验项,所以只有更新的操作才进行校验。

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

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

相关文章

大数据面试题--kafka夺命连环问

1、kafka消息发送的流程&#xff1f; 在消息发送过程中涉及到两个线程&#xff1a;一个是 main 线程和一个 sender 线程。在 main 线程中创建了一个双端队列 RecordAccumulator。main 线程将消息发送给双端队列&#xff0c;sender 线程不断从双端队列 RecordAccumulator 中拉取…

QT信号和槽与自定义的信号和槽

QT信号和槽与自定义的信号和槽 1.概述 这篇文章介绍下QT信号和槽的入门知识&#xff0c;通过一个案例介绍如何创建信号和槽&#xff0c;并调用他们。 2.信号和槽使用 下面通过点击按钮关闭窗口的案例介绍如何使用信号和槽。 创建按钮 在widget.cpp文件中创建按钮代码如下 …

unity显示获取 年月日周几【日期】

unity显示获取 年月日周几【日期】 public void ShowDate(Text txt){//txt.text DateTime now DateTime.Now; // 获取当前时间int year now.Year; // 获取年份int month now.Month; // 获取月份&#xff08;1-12&#xff09;int day now.Day; // 获取天数&#xff08;1-31&…

emr上使用sparkrunner运行beam数据流水线

参考资料 https://time.geekbang.org/column/intro/167?tabcatalog Apache Beam和其他开源项目不太一样&#xff0c;它并不是一个数据处理平台&#xff0c;本身也无法对数据进行处理。Beam所提供的是一个统一的编程模型思想&#xff0c;而我们可以通过这个统一出来的接口来编…

AUTOSAR CP SocketAdaptor(SoAd)规范导读

《AUTOSAR_SWS_SocketAdaptor》规范的主要内容包括&#xff1a; 简介和功能概述&#xff1a;说明了 AUTOSAR 基本软件模块 Socket Adaptor&#xff08;SoAd&#xff09;的功能、API 和配置。数据传输的 TCP/IP 概念在计算和电信环境中已成为标准&#xff0c;应用程序的寻址等…

代码随想录-栈和队列-用栈实现队列

问题描述 题目描述中有说不存在空栈的pop和peek&#xff0c;所以无需判断这个 解析 重点在于思路&#xff0c;代码白给。 要用栈实现队列&#xff0c;肯定是两个栈才可以。一个做入队操作&#xff0c;一个做出队操作。 首先入队简单&#xff0c;往栈里加就完事了。 出队复…

【设计模式】结构型模式(四):组合模式、享元模式

《设计模式之结构型模式》系列&#xff0c;共包含以下文章&#xff1a; 结构型模式&#xff08;一&#xff09;&#xff1a;适配器模式、装饰器模式结构型模式&#xff08;二&#xff09;&#xff1a;代理模式结构型模式&#xff08;三&#xff09;&#xff1a;桥接模式、外观…

轻型民用无人驾驶航空器安全操控------理论考试多旋翼部分笔记

官网&#xff1a;民用无人驾驶航空器综合管理平台 (caac.gov.cn) 说明&#xff1a;一是法规部分&#xff1b;二是多旋翼部分 本笔记全部来源于轻型民用无人驾驶航空器安全操控视频讲解平台 目录 官网&#xff1a;民用无人驾驶航空器综合管理平台 (caac.gov.cn) 一、轻型民用无人…

【leetcode练习·二叉树】用「分解问题」思维解题 I

本文参考labuladong算法笔记[【强化练习】用「分解问题」思维解题 I | labuladong 的算法笔记] 105. 从前序与中序遍历序列构造二叉树 | 力扣 | LeetCode | 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵…

深入解析四种核心网络设备:集线器、桥接器、路由器和交换机

计算机网络系列课程《网络核心设备》 在现代网络技术中&#xff0c;集线器、桥接器、路由器和交换机扮演着至关重要的角色。本文&#xff0c;将深入探讨这四种设备的功能、工作原理及其在网络架构中的重要性。 集线器&#xff1a;基础网络连接设备 集线器&#xff08;Hub&…

宏景eHR uploadLogo.do 任意文件上传致RCE漏洞复现

0x01 产品简介 宏景eHR人力资源管理软件是一款专为复杂单组织或多组织客户设计的人力资源管理软件,融合了最新的互联网技术和先进的人力资源管理理念和实践。宏景eHR软件支持B/S架构,特别适合集团化管理和跨地域使用。它提供了全面的人力资源管理功能,包括人员、组织机构、…

ssm基于JAVA的网上订餐管理系统+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码看文章最下面 需要定制看文章最下面 目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容…

NVR设备ONVIF接入平台EasyCVR私有化部署视频平台如何安装欧拉OpenEuler 20.3 MySQL

在当今数字化时代&#xff0c;安防视频监控系统已成为保障公共安全和个人财产安全的重要工具。NVR设备ONVIF接入平台EasyCVR作为一款功能强大的智能视频监控管理平台&#xff0c;它不仅提供了视频远程监控、录像、存储与回放等基础功能&#xff0c;还涵盖了视频转码、视频快照、…

测试网空投进行中 — 全面了解 DePIN 赛道潜力项目 ICN Protocol 及其不可错过的早期红利

随着云计算技术的飞速发展&#xff0c;越来越多的企业和个人对云服务的需求变得多样化且复杂化。然而&#xff0c;传统的中心化云服务平台&#xff08;如AWS、微软Azure等&#xff09;往往存在着高成本、数据隐私保护不足以及灵活性差等问题。 为了解决这些挑战&#xff0c;Imp…

CulturalBench :一个旨在评估大型语言模型在全球不同文化背景下知识掌握情况的基准测试数据集

2024-10-04&#xff0c;为了提升大型语言模型在不同文化背景下的实用性&#xff0c;华盛顿大学、艾伦人工智能研究所等机构联合创建了CulturalBench。这个数据集包含1,227个由人类编写和验证的问题&#xff0c;覆盖了包括被边缘化地区在内的45个全球区域。CulturalBench的推出&…

CAD VBA 图元颜色跟随图层

效果如下&#xff1a; 一、所有图元颜色为bylayer Sub 图元颜色跟随图层() Dim item As AcadEntityFor Each item In ThisDrawing.ModelSpace item.color acByLayer Next ThisDrawing.Regen acActiveViewport End Sub二、与图层颜色相同&#xff08;不是bylayer&#xff09;:…

介绍一下数组(c基础)(smart 版)

c初期&#xff0c;记住规则&#xff0c;用规则。 我只是介绍规则。&#xff08;有详细版&#xff0c;这适合smart人看&#xff09; 数组&#xff08;同类型&#xff09; int arr[n] {} ; int 是 元素类型。 int arr[n] {} ; arr为标识符。 {} 集合&#xff0c;元素有次…

【数据结构】插入排序——直接插入排序 和 希尔排序

直接插入排序 和 希尔排序 一、直接插入排序二、直接插入排序的弊端三、希尔排序&#xff08;1&#xff09;对插入排序的联想&#xff08;2&#xff09;希尔排序的思路 四、直接插入排序和希尔排序效率对比1>随机生成10000个数2>我们随机生成100000个数3>我们随机生成…

python使用turtle画图快速入门,轻松完成作业练习

turtle介绍 turtle是一个绘图库&#xff0c;可以通过编程进行绘图。其模拟了一个乌龟在屏幕上的运动过程。该库通常用于给青少年学习编程&#xff0c;当然&#xff0c;也可以使用其进行作图。 在一些学校中&#xff0c;可能在python学习的课程中&#xff0c;要求完成turtle绘…

K8S群集调度二

一、污点(Taint) 和 容忍(Tolerations) 1.1、污点(Taint) 设置在node上是对pod的一种作用 节点的亲和性&#xff0c;是Pod的一种属性&#xff08;偏好或硬性要求&#xff09;&#xff0c;它使Pod被吸引到一类特定的节点 而Taint 则相反&#xff0c;它使节点能够排斥一类特…