【Springboot】基础业务学习笔记

参数校验

方法步骤

1.引入Spring Validation起步依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2.在参数面前添加@Pattern注解

@Pattern(regexp = "^\\S{5,16}$")

3.在Controller类上添加 @Vallidated 注解

参数校验失败异常处理

@RestControllerAdvice
public class GlobalExceptionHandle {@ExceptionHandler(Exception.class)public Result handleException(Exception e) {e.printStackTrace();return Result.error(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : "操作失败");}
}

其中,Resul类是自定义的返回结果类

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Result<T> {private Integer code;//业务状态码  0-成功  1-失败private String message;//提示信息private T data;//响应数据//快速返回操作成功响应结果(带响应数据)public static <E> Result<E> success(E data) {return new Result<>(0, "操作成功", data);}//快速返回操作成功响应结果public static Result success() {return new Result(0, "操作成功", null);}public static Result error(String message) {return new Result(1, message, null);}
}

封装好的实体对象校验

User对象为例

对指定属性值加上 Validation对应注解

@NotNull值不能为空
@NotEmpty不能为空且字符串不能为空字符串""
@Email满足邮箱格式
@URL对参数是否是url路径进行校验

@Data
public class User {@NotNullprivate Integer id;//主键IDprivate String username;//用户名@JsonIgnore //让springmvc把当前对象转换成json字符串的时候,忽略password,最终的json字符串中就没有password这个属性了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;//更新时间
}

方法参数前添加注解

@Validated

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

分组校验

将校验项归类分组,校验指定组中的校验项。

在实体类内部定义接口,通过groups属性进行指定,给 @validated注解的value属性赋值,默认为Default

@Data
public class Category {@NotNull(groups = Update.class)private Integer id;//主键ID@NotEmptyprivate String categoryName;//分类名称@NotEmptyprivate String categoryAlias;//分类别名private Integer createUser;//创建人ID@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;//创建时间@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime updateTime;//更新时间//如果说某个校验项没有指定分组,默认属于Default分组//分组之间可以继承, A extends B  那么A中拥有B中所有的校验项public interface Add extends Default {}public interface Update extends Default{}
}

这种情况下,id的校验是在更新的时候去判断传入的参数是否为空。

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

Controller在参数中指明当前实体类校验的类型

自定义校验

已有的注解不能满足所有的校验需求,特殊的情况需要自定义校验(自定义校验注解)

1.自定义注解State

@Documented
// 指定校验规则由谁提供
@Constraint(validatedBy = {StateValidation.class}
)
// 元注解 标明该注解的使用范围
/*** ElementType.METHOD 方法体,* ElementType.FIELD 属性,* ElementType.ANNOTATION_TYPE 注释类,* ElementType.CONSTRUCTOR 构造,* ElementType.PARAMETER 参数,* ElementType.TYPE_USE*/
@Target({ElementType.FIELD})
// 注解保留阶段
@Retention(RetentionPolicy.RUNTIME)
public @interface State {// 提供校验失败后的信息String message() default "state 参数的值只能是已发布或草稿";// 指定分组Class<?>[] groups() default {};// 负载 获取到 State 注解的附加信息Class<? extends Payload>[] payload() default {};
}

2.自定义校验数据的类 StateValidation 实现 ConstraintValidator接口

public class StateValidation  implements ConstraintValidator<State, String> {@Overridepublic boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {if (value == null) return false;if (value.equals("已发布") || value.equals("草稿")) {return true;}return false;}
}

3.在需要校验的地方使用自定义注解

登录认证

令牌规范JWT

全称:JSON Web Token (https:/jwt.io/

组成:

Header(),记录令牌类型和签名算法等
PayLoad(载荷),携带自定义的信息。注意不要承载私密数据。
Signature(签名),对头部和载荷进行加密计算得来

使用步骤

1.添加依赖

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version>
</dependency>

2.调用API生成和校验令牌

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;
import java.util.Map;public class JwtUtil {private static final String KEY = "itheima"; // 令牌加密密钥字符串//接收业务数据,生成token并返回public static String genToken(Map<String, Object> claims) {return JWT.create().withClaim("claims", claims) // 设置令牌承载数据.withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 12)) // 设置令牌失效时间.sign(Algorithm.HMAC256(KEY)); // 设置令牌加密算法}//接收token,验证token,并返回业务数据public static Map<String, Object> parseToken(String token) {return JWT.require(Algorithm.HMAC256(KEY)).build().verify(token).getClaim("claims").asMap();}
}

3.解析令牌抛出异常,则令牌被篡改或过期

单个设置登录验证

Token在请求头中的Authorization字段,从请求头中获取。若未登录,则不存在该字段。

	@GetMapping("/list")public Result<String> list(@RequestHeader(name = "Authorization") String token, HttpServletResponse response) {// 验证Tokentry {Map<String, Object> claims = JwtUtil.parseToken(token);return Result.success("所有文章数据");} catch (Exception e) {// 设置响应状态码 401response.setStatus(401);return Result.error("未登录");}}

设置拦截器进行登录验证

首先设置登录拦截器

@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 令牌验证String token = request.getHeader("Authorization");try {Map<String, Object> claims = JwtUtil.parseToken(token);// 放行return true;} catch (Exception e) {// 设置响应状态码 401response.setStatus(401);// 不放行return false;}}
}

随后配置注册拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 登录和注册接口不拦截registry.addInterceptor(loginInterceptor).excludePathPatterns("/user/login", "/user/register");}
}

ThreadLocal

用来存取数据:set()/get()
使用ThreadLocal存储的数据,线程安全
用完记得调用remove方法释放

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

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

相关文章

CanFestival结合Android来完成canopen通信

1.准备开发环境 安装Android Studio和NDK后&#xff0c;需要在Android Studio中创建一个新的NDK项目&#xff0c;并且在项目目录下创建一个jni目录来放置NDK代码。 配置CAN总线接口硬件需要根据具体的硬件要求进行&#xff0c;常见的方法包括使用串口或USB连接CAN总线接口&…

PyTorch Tutorial

本文作为博客“Transformer - Attention is all you need 论文阅读”的补充内容&#xff0c;阅读的内容来自于 https://pytorch.org/tutorials/intermediate/char_rnn_classification_tutorial.html#recommended-preparation 建议的准备流程。 Deep Learning with PyTorch: …

网络知识-以太网技术的发展及网络设备

目 录 一、背景介绍 &#xff08;一&#xff09;网络技术的时代 &#xff08;二&#xff09;以太网技术脱颖而出 二、以太网的工作原理 &#xff08;一&#xff09;、载波侦听多路访问&#xff08;CSMA/CD&#xff09; 1、数据发送流程 2、发送过程解析 3、…

np.eye()函数的使用

背景&#xff1a;今天在复现一篇3D图像分割论文的时候&#xff0c;思考了一个问题&#xff0c;我们的数据集一般由原始数据和对应的Ground Truth组成&#xff0c;一般的3D数据都是(Height,Width,Depth)的形状&#xff0c;而对应的Ground Truth也是(Height,Width,Depth)的形状。…

WeNet语音识别+Qwen-72B-Chat Bot+Sambert-Hifigan语音合成

WeNet语音识别Qwen-72B-Chat Bot&#x1f47e;Sambert-Hifigan语音合成 简介 利用 WeNet 进行语音识别&#xff0c;使用户能够通过语音输入与系统进行交互。接着&#xff0c;Qwen-72B-Chat Bot作为聊天机器人接收用户的语音输入或文本输入&#xff0c;提供响应并与用户进行对话…

RPC基础知识总结

RPC 是什么? RPC&#xff08;Remote Procedure Call&#xff09; 即远程过程调用&#xff0c;通过名字我们就能看出 RPC 关注的是远程调用而非本地调用。 为什么要 RPC &#xff1f; 因为&#xff0c;两个不同的服务器上的服务提供的方法不在一个内存空间&#xff0c;所以&am…

k8s安装hostPath方式存储的PostgreSQL15

1.配置 PostgreSQL 的 ConfigMap cat > postgres-configmap.yaml << EOF apiVersion: v1 kind: ConfigMap metadata:name: postgres-configlabels:app: postgresnamespace: dev data:POSTGRES_DB: postgresdbPOSTGRES_USER: postgresadminPOSTGRES_PASSWORD: admin12…

软件测试/测试开发丨Vuetify框架的使用

介绍 Vuetify 是一个基于 Vue.js 精心打造 UI 组件库&#xff0c;整套 UI 设计为 Material 风格。能够让没有任何设计技能的开发者创造出时尚的 Material 风格界面。 为什么要使用Vuetify框架 所有组件遵从 Material Design 设计规范&#xff0c;UI 体验非常优秀&#xff0c…

09-C++ STL-适配器、算法

c STL-适配器、算法 1. 函数对象 1.1 概念 重载函数调用操作符的类&#xff0c;其对象常称为函数对象&#xff08;function object&#xff09;&#xff0c;即它们是行为类似函数的对象&#xff0c;也叫仿函数(functor)&#xff0c; 其实就是 重载“()”操作符&#xff0c;使…

JSON的一些资源

以下是一些推荐的学习资源&#xff1a; 1. **官方网站**: - JSON.org: 这是一个很好的起点&#xff0c;它提供了JSON的基本介绍和语法规则。 2. **在线教程和课程**: - CSDN全方面学习各种资源。 - W3Schools (w3schools.com): 提供了一个关于JSON的教程&#xff0c;涵…

zookeeper经典应用场景之分布式锁

1. 什么是分布式锁 在单体的应用开发场景中涉及并发同步的时候&#xff0c;大家往往采用Synchronized&#xff08;同步&#xff09;或者其他同一个JVM内Lock机制来解决多线程间的同步问题。在分布式集群工作的开发场景中&#xff0c;就需要一种更加高级的锁机制来处理跨机器的进…

MiniTab的宏基础知识

什么是宏&#xff1f; 宏是包含一系列 Minitab 会话命令的文本文件。可以使用宏自动执行重复性任务&#xff08;例如&#xff0c;生成月度报表&#xff09;或扩展 Minitab 的功能&#xff08;例如&#xff0c;计算特殊检验统计量&#xff09;。 Minitab 提供以下类型的宏&…

MongoDB索引详解

概述 索引是一种用来快速查询数据的数据结构。BTree 就是一种常用的数据库索引数据结构&#xff0c;MongoDB 采用 BTree 做索引&#xff0c;索引创建 colletions 上。MongoDB 不使用索引的查询&#xff0c;先扫描所有的文档&#xff0c;再匹配符合条件的文档。使用索引的查询&…

axios post YII2无法接收post参数问题解决

axios post YII2无法接收post参数问题解决 在yii 配置文件中增加 ‘parsers’ > [“application/json” > “yii\web\JsonParser”] 如下所示&#xff1a; $config [id > basic,language > zh-CN,timeZone > env(TIME_ZONE, PRC),basePath > $basePath,bo…

Spring IOC的四种手动注入方法

手动注入 1.Set方法注入-五种类型的注入1.1 业务对象JavaBean第一步&#xff1a;创建dao包下的UserDao类第二步&#xff1a;属性字段提供set⽅法第三步&#xff1a;配置⽂件的bean标签设置property标签第四步&#xff1a;测试 1.2 常用对象String&#xff08;日期类型&#xff…

Adobe Photoshop 快捷键

PS快捷键 图层 选择图层 Ctrl T&#xff1a;可以对图层的大小和位置进行调整 填充图层 MAC: AltBackspace (前景) or CtrlBackspace (背景) WINDOWS: AltDelete (前景) or CtrlDelete (背景) 快速将图层填充为前景色或背景色 平面化图层&#xff08;盖印图层&#xff09…

每日一题——LeetCode1089.复写0

方法一 splice&#xff1a; 通过数组的slice方法&#xff0c;碰到 0就在后面加一个0&#xff0c;最后截取原数组的长度&#xff0c;舍弃后面部分。 但这样做是违反了题目的要求&#xff0c;不要在超过该数组长度的位置写入元素。 var duplicateZeros function(arr) {var le…

软件测试|全面解析Docker Start/Stop/Restart命令:管理容器生命周期的必备工具

简介 Docker是一种流行的容器化平台&#xff0c;用于构建、分发和运行应用程序。在使用Docker时&#xff0c;经常需要管理容器的生命周期&#xff0c;包括启动、停止和重启容器。本文将详细介绍Docker中的docker start、docker stop和docker restart命令&#xff0c;帮助您全面…

Python条形图热图直方图可视化精神健康状态(医学数据集)

目标是比开源精神疾病提供的基本报告更深入地挖掘&#xff0c;并了解更多属性之间的相互作用&#xff0c;这可以为所描述的决策者提供信息。 考虑的问题点&#xff1a; 不同性别属性的员工心理健康是否存在显着差异&#xff1f;不同年龄属性的员工心理健康是否存在显着差异&a…

Go语言程序设计-第7章--接口

Go语言程序设计-第7章–接口 接口类型是对其他类型行为的概括与抽象。 Go 语言的接口的独特之处在于它是隐式实现。对于一个具体的类型&#xff0c;无须声明它实现了哪些接口&#xff0c;只要提供接口所必须实现的方法即可。 7.1 接口即约定 7.2 接口类型 package iotype …