【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.rhkb.cn/news/468362.html

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

相关文章

HarmonyOS入门 : 获取网络数据,并渲染到界面上

1. 环境搭建 开发HarmonyOS需要安装DevEco Studio&#xff0c;下载地址 : https://developer.huawei.com/consumer/cn/deveco-studio/ 2. 如何入门 入门HarmonyOS我们可以从一个实际的小例子入手&#xff0c;比如获取网络数据&#xff0c;并将其渲染到界面上。 本文就是基于…

AndroidStudio-视图基础

一、设置视图的宽高 1.在XML文件中设置视图宽高 视图宽度通过属性android:layout_width表达&#xff0c;视图高度通过属性android:layout_height表达&#xff0c;宽高的取值主要有下列三种: &#xff08;1&#xff09;wrap_content:表示与内容自适应。对于文本视图来说&…

三菱QD77MS定位模块紧急停止功能

“紧急停止功能” 是通过简单运动模块的外部输入连接用连接器上连接的紧急停止输入&#xff0c;对同服放大器的全部轴进行批量停止的功能。(初始值为“0:有效”。)通过“[r.82]紧急停止有效/无效设置”可以选择紧急停止输入的有效/无效。 [1]控制内容 将“[r82]紧急停止有效/无…

Android JNI 技术入门指南

引言 在Android开发中&#xff0c;Java是一种主要的编程语言&#xff0c;然而&#xff0c;对于一些性能要求较高的场景&#xff08;如音视频处理、图像处理、计算密集型任务等&#xff09;&#xff0c;我们可能需要使用到C或C等语言来编写底层的高效代码。为了实现Java代码与C…

Js — 定时器

有两种&#xff1a;setInterval 和 setTimeout 间隔时间单位为毫秒 setInterval 每隔指定的毫秒数重复执行一个函数或代码 开启定时器&#xff1a;setInterval(函数&#xff0c;间隔时间) 作用&#xff1a;每隔一段时间调用这个函数 注意&#xff1a;它不是立即执行&#x…

H5播放器EasyPlayer.js 流媒体播放器是否支持npm(yarn) install 安装?

EasyPlayer.js H5播放器是一款功能强大的H5视频播放器&#xff0c;它支持多种流媒体协议播放&#xff0c;包括WebSocket-FLV、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WebRTC等格式的视频流。它不仅支持H.264和H.265编码格式&#xff0c;还具备实时录像、低延时直播等功能…

前端刺客系列----Vue 3 入门介绍

目录 一.什么是 Vue 3&#xff1f; 二.Vue 3 的主要特性 三,Vue3项目实战 四.总结 在前端开发的世界里&#xff0c;Vue.js 作为一款渐进式的 JavaScript 框架&#xff0c;已成为许多开发者的首选工具。自从 Vue 3 发布以来&#xff0c;它带来了许多重要的改进和新特性&…

【论文复现】MSA+抑郁症模型总结(三)

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀MSA抑郁症模型 热门研究领域&#xff1a;情感计算的横向发展1. 概述2. 论文地址3. 研究背景4. 主要贡献5. 模型结构和代码6. 数据集介绍7. 性…

Linux 实验:日志的备份与恢复 xfs文件系统

添加一个新的硬盘&#xff0c;创建硬盘分区sdc1 设置文件系统格式xfs&#xff0c;提示安装xfsprogs&#xff0c;如果安装失败&#xff0c;在后缀加上--fix-missing直到安装完成为止 mkdir创建空目录data&#xff0c;将sdc1挂载到data&#xff0c;data是根目录下新建的目录&…

应对AI与机器学习的安全与授权管理新挑战,CodeMeter不断创新引领保护方案

人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术正在快速发展&#xff0c;逐渐应用到全球各类主流系统、设备及关键应用场景中&#xff0c;尤其是在政府、商业和工业组织不断加深互联的情况下&#xff0c;AI和ML技术的影响日益广泛。虽然AI技术的…

证书学习(六)TSA 时间戳服务器原理 + 7 个免费时间戳服务器地址

目录 一、简介1.1 什么是时间戳服务器1.2 名词扩展1.3 用时间戳标记顺序1.4 7 个免费TSA时间戳服务器地址(亲测可用)1.5 RFC 3161 标准二、时间戳原理2.1 时间戳服务工作流程2.2 验证工作流程2.3 举个例子2.4 时间戳原理总结三、代码实现3.1 curl 命令请求时间戳3.2 java 代码…

一文快速预览经典深度学习模型(一)——CNN、RNN、LSTM、Transformer、ViT

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本文主要简要并通俗地介绍了几种经典的深度学习模型&#xff0c;如CNN、RNN、LSTM、Transformer、ViT&#xff08;Vision Transformer&#xff09;等&#xff0c;便于大家初探深度学习的相关知识&#xff0c;并更好地理解深度学…

如何运营Github Org

目录 前言 正文 关于分支保护 特别说明 如何在Windows环境下配置GitHub Desktop GPG签名&#xff1f; 推荐分支保护选择 关于good first issue 如何设置good first issue&#xff1f; 关于Project 尾声 &#x1f52d; Hi,I’m Pleasure1234&#x1f331; I’m currently learni…

接收nVisual中rabbitmq数据不成功问题排查

rabbitmq服务部署成功的情况下&#xff0c;消息对接不成功一般原因为消息发送失败&#xff0c;发送失败大多数可能为global_settings表配置错误。下面从两个方面解决消息对接不成功问题。 1.数据是否成功发送 检查global_settings表中rabbitmq发送消息配置信息是否正确 #MQS…

二叉树的实现

一.树 1.1树的概念与结构 树是一种非线性数据结构&#xff0c;由有限个结点组成的具有层次关系的集合。树的根部位置就叫根结点&#xff0c;除根结点以外&#xff0c;其余的树被分为各个互不相交的集合。树的根系只能向下延伸不能向左右延伸。除根结点以外每个结点有且仅有一…

Python基础学习-03逻辑分支语句、循环

目录 1、记住逻辑关系 2、逻辑分支语句 3、for-loop循环 4、while-loop 5、break 和 continue 6、本节总结 1、记住逻辑关系 • 逻辑关系 1&#xff09; True&#xff08;真&#xff09; 和 False&#xff08;假&#xff09; 2&#xff09;逻辑关系有 and&#xff08;与…

Spark中给读取到的数据 的列 重命名的几种方式!

目录 一、第一种 (withColumnRenamed) 二、第二种&#xff08;toDF&#xff09; 三、第三种&#xff08; toDF(*tuple1) &#xff09; 四、 第四种(schema) 五、假如文件里自带有列名的情况&#xff08;option&#xff09; 一、第一种 (withColumnRenamed) 假设要把如下…

鸿蒙UI开发——实现环形文字

1、背 景 有朋友提问&#xff1a;您好关于鸿蒙UI想咨询一个问题 如果我想实现展示环形文字是需要通过在Text组件中设置transition来实现么&#xff0c;还是需要通过其他方式来实现。 针对这位粉丝朋友的提问&#xff0c;我们做一下解答。 2、实现环形文字效果 ❓ 什么是环形…

现场工程师日记-MSYS2迅速部署PostgreSQL主从备份数据库

文章目录 一、概要二、整体架构流程1. 安装 MSYS2 环境2. 安装postgresql 三、技术名词解释1.MSYS22.postgresql 四、技术细节1. 创建主数据库2.添加从数据库复制权限3. 按需修改参数&#xff08;1&#xff09;WAL保留空间&#xff08;2&#xff09;监听地址 4. 启动主服务器5.…

Rust-AOP编程实战

文章本天成,妙手偶得之。粹然无疵瑕,岂复须人为?君看古彝器,巧拙两无施。汉最近先秦,固已殊淳漓。胡部何为者,豪竹杂哀丝。后夔不复作,千载谁与期? ——《文章》宋陆游 【哲理】文章本是不加人工,天然而成的,是技艺高超的人在偶然间所得到的。其实作者所说的“天成”…