项目统一处理
统一结果返回
1、统一自定义返回状态码
2、统一封装返回对象
3、自定义响应消息
4、测试
统一异常处理
1、全局异常处理
2、将异常信息写到日志文件中
3、全局异常处理返回信息
4、测试
统一参数校验
1、添加依赖
2、注解介绍
validator内置注解
注解 | 详细信息 |
---|---|
@Null |
被注释的元素必须为 null |
@NotNull |
被注释的元素必须不为 null |
@AssertTrue |
被注释的元素必须为 true |
@AssertFalse |
被注释的元素必须为 false |
@Min(value) |
被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Max(value) |
被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@DecimalMin(value) |
被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@DecimalMax(value) |
被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@Size(max, min) |
被注释的元素的大小必须在指定的范围内 |
@Digits (integer, fraction) |
被注释的元素必须是一个数字,其值必须在可接受的范围内 |
@Past |
被注释的元素必须是一个过去的日期 |
@Future |
被注释的元素必须是一个将来的日期 |
@Pattern(value) |
被注释的元素必须符合指定的正则表达式 |
Hibernate Validator 附加的 constraint
注解 | 详细信息 |
---|---|
@Email |
被注释的元素必须是电子邮箱地址 |
@Length |
被注释的字符串的大小必须在指定的范围内 |
@NotEmpty |
被注释的字符串的必须非空 |
@NotBlank |
被验证字符串非null,且长度必须大于0 |
@Range |
被注释的元素必须在合适的范围内 |
注意:
- @NotNull 适用于任何类型被注解的元素必须不能与NULL
- @NotEmpty 适用于String Map或者数组不能为Null且长度必须大于0
- @NotBlank 只能用于String上面 不能为null,调用trim()后,长度必须大于0
3、全局异常处理
如果校验失败,会抛出MethodArgumentNotValidException或者ConstraintViolationException异常。在实际项目开发中,通常会用统一异常处理来返回一个更友好的提示。代码如下
4、常用校验
通常有这三种方式获取参数,所以对这些形式进行验证
1、请求路径参数
-
@PathVariable(不能为空,不能设置默认值,因为null对于url是无意义的)
获取路径参数。即url/{id}这种形式。
-
@RequestParam
获取查询参数。即url?name=这种形式
2、Body参数
-
@PostMapping组合@RequestBody注解
-
@PostMapping无@RequestBody注解
3、请求头参数以及Cookie
- @RequestHeader
- @CookieValue
测试demo如下:
注意:
对@PostMapping请求验证参数,直接在参数上添加@Validated或者@Valid。
对@RequestParam验证参数,直接在参数上添加@Validated是无效的,使用@Valid也无效,需要在类上添加@Validated,然后在参数上使用注解验证。
5、分组校验
在实际项目中,可能多个方法需要使用同一个对象来接收参数,而不同方法的校验规则很可能是不一样的。这个时候,简单地在对象的字段上加约束注解无法解决这个问题。因此,spring-validation支持了分组校验的功能,专门用来解决这类问题。比如保存User的时候,UserId是可空的,但是更新User的时候,UserId的值必须>=10000000000000000L;其它字段的校验规则在两种情况下一样。
1、约束注解上声明适用的分组信息groups
2、@Validated注解上指定校验分组
6、嵌套校验
在嵌套的类上必须标记@Valid注解,如要对UserVO的属性CarVO的carNum校验,UserVO引入CarV0须标记@Valid注解
7、集合校验
如果请求体直接传递了json数组给后台,并希望对数组中的每一项都进行参数校验。此时,如果我们直接使用java.util.Collection下的list或者set来接收数据,参数校验并不会生效!我们可以使用自定义list集合来接收参数:
包装List类型,并声明@Valid注解
8、自定义校验
Hibernate Validator提供的校验无法满足当前需求时,可以使用Validator
自定义注解进行特殊校验。
1、自定义电话校验
这个注解是作用在Field字段上,运行时生效,触发的是PhoneValid这个验证类。
- message 定制化的提示信息,主要是从ValidationMessages.properties里提取,也可以依据实际情况进行定制
- groups 这里主要进行将validator进行分类,不同的类group中会执行不同的validator操作
- payload 主要是针对bean的,使用不多。
2、电话真正进行验证的逻辑代码
要对异常MethodArgumentNotValidException进行拦截处理。
3、测试
补充身份证验证
统一日志处理
日志的框架比较丰富,spring boot集成了logback,因此推荐使用logback在项目中使用。
配置
在resources里创建日志配置文件logback-spring.xml,配置内容如下:
归档日志效果
注意
- 日志的环境即spring.profiles.acticve,跟随项目启动;
- 启动后,即可到自定目录查找到生成的日志文件;
- 本地idea调试时,推荐Grep Console插件可实现控制台的自定义颜色输出,插件地址:https://plugins.jetbrains.com/plugin/7125-grep-console
统一处理Web请求日志
统一处理Web请求的日志,方便排查问题
统一空指针处理
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。
类方法
序号 | 方法 & 描述 |
---|---|
1 | static |
2 | boolean equals(Object obj)判断其他对象是否等于 Optional。 |
3 | Optional |
4 | Optional flatMap(Function<? super T,Optional> mapper)如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional |
5 | T get()如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException |
6 | int hashCode()返回存在值的哈希码,如果值不存在 返回 0。 |
7 | void ifPresent(Consumer<? super T> consumer)如果值存在则使用该值调用 consumer , 否则不做任何事情。 |
8 | boolean isPresent()如果值存在则方法会返回true,否则返回 false。 |
9 | Optional map(Function<? super T,? extends U> mapper)如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional。 |
10 | static |
11 | static |
12 | T orElse(T other)如果存在该值,返回值, 否则返回 other。 |
13 | T orElseGet(Supplier<? extends T> other)如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。 |
14 | |
15 | String toString()返回一个Optional的非空字符串,用来调试 |
实战案例
demo1
demo2
demo3
采用这种链式编程,虽然代码优雅了。但是,逻辑性没那么明显,可读性有所降低。
__EOF__

本文链接:https://www.cnblogs.com/bigfairy/p/14373457.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!