当前位置:网站首页>JRS303-Data Verification
JRS303-Data Verification
2022-08-11 07:51:00 【flower padded jacket】
🧑 个人主页:花棉袄
本章内容:【JRS303-数据校验】
版权: 本文由【花棉袄】原创在CSDN首发需要转载请联系博主

如果文章对你有帮助【关注点赞️收藏】
JSR303介绍
- 在Java中提供了一系列的校验方式
- These verification methods are in“javax.validation.constraints”包中
- 提供了如@Email,@NotNull等注解
1️⃣引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- 在非空处理方式上提供了@NotNull,@NotBlank和@NotEmpty
2️⃣常用注解
- All validation annotations are there:
javax.validation.constraints包下
@NotNull
- 注解元素禁止为null,能够接收任何类型
@NotEmpty
- 该注解修饰的字段不能为null或""
- 支持以下几种类型
集合长度的计算
Map (map size is evaluated)
map长度的计算
Array (array length is evaluated)
数组长度的计算
@NotBlank
- 该注解不能为null,并且至少包含一个非空格字符
- 接收字符序列
3️⃣开启校验
@Valid
- controller中加校验注解@Valid,开启校验
🥌数据校验测试
- 步骤1:Use validation annotations on entity class fields @NotNull @NotEmpty @NotBlank @Pattern
- 步骤2:controller中加校验注解@Valid,开启校验
- 步骤3:给校验的Bean后,紧跟一个BindResult,就可以获取到校验的结果,拿到校验的结果,就可以自定义的封装
public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){
}
- Add annotations to entities
@Data
public class Student {
@NotEmpty(message ="姓名不能为空")
private String name;
}
- controllerLayer save method added:@Valid
@RestController
public class TestController {
@RequestMapping("/test")
public Result test(@Valid @RequestBody Student student, BindingResult result) {
String name = student.getName();
HashMap<String, Object> map = new HashMap<>();
map.put("name",name);
map.put("errors",result.getFieldErrors());
return Result.ok(map,"数据校验");
}
}
- ️ 测试:http://localhost:8080/test
{
"name":""
}
- ️ 返回信息
{
"code": 200,
"msg": "数据校验",
"data": {
"name": "",
"errors": [
{
"codes": [
"NotEmpty.student.name",
"NotEmpty.name",
"NotEmpty.java.lang.String",
"NotEmpty"
],
"arguments": [
{
"codes": [
"student.name",
"name"
],
"arguments": null,
"defaultMessage": "name",
"code": "name"
}
],
"defaultMessage": "姓名不能为空",
"objectName": "student",
"field": "name",
"rejectedValue": "",
"bindingFailure": false,
"code": "NotEmpty"
}
]
}
}
1️⃣Custom package error message
@RestController
public class TestController {
@RequestMapping("/test")
public Result test(@Valid @RequestBody Student student, BindingResult result) {
String name = student.getName();
Map<String, String> map = new HashMap<>();
map.put("name", name);
if (result.hasErrors()) {
//1.获取错误的校验结果
result.getFieldErrors().forEach((item) -> {
//2.获取发生错误时的message
String message = item.getDefaultMessage();
//3.获取发生错误的字段
String field = item.getField();
map.put(field, message);
});
return Result.fail(map, "数据校验");
} else {
return Result.ok(map);
}
}
}
- ️ 测试:http://localhost:8080/test
{
"name":""
}
- ️ 错误信息
{
"code": 500,
"msg": "数据校验",
"data": {
"name": "姓名不能为空"
}
}
2️⃣统一异常处理
- springmvc统一处理异常
@Slf4j
@RestControllerAdvice(basePackages = "com.michale.jrs303.controllers")
public class FireflyMallExceptionControllerAdvice {
/** * Handle data validation issues * @param e * @return */
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Result handleVaildException(MethodArgumentNotValidException e) {
log.error("数据校验出现问题:{},异常类型:{}", e.getMessage(), e.getClass());
BindingResult bindingResult = e.getBindingResult();
Map<String, String> errorMap = new HashMap();
bindingResult.getFieldErrors().forEach((fieldError) -> {
errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
});
return Result.fail(errorMap, "数据校验出现问题");
}
/** * 处理其他异常 * @param throwable * @return */
@ExceptionHandler(value = Throwable.class)
public Result handleException(Throwable throwable) {
return Result.fail();
}
}
@RequestMapping("/testException")
public Result testException(@Valid @RequestBody Student student) {
String name = student.getName();
Map<String, String> map = new HashMap<>();
map.put("name", name);
return Result.ok(map);
}
- ️ 测试统一异常处理:测试:http://localhost:8080/testException
{
"name":"",
}
- ️ 错误信息
{
"code": 500,
"msg": "数据校验出现问题",
"data": {
"name": "姓名不能为空"
}
}
JSR303分组校验
1️⃣Create a packet check interface
/** * @Author 天才小狐狸 * @Data 2022/8/11 2:03 * @Description Name check group */
public interface NameGroup {
}
/** * @Author 天才小狐狸 * @Data 2022/8/11 2:04 * @Description Age verification grouping */
public interface AgeGroup {
}
2️⃣添加校验注解
@Data
public class Student {
@NotEmpty(message ="姓名不能为空",groups = NameGroup.class)
private String name;
@NotEmpty(message ="Nickname cannot be empty",groups = NameGroup.class)
private String nickName;
@Min(value = 18,message = "The minimum age limit cannot be lower18岁" ,groups = AgeGroup.class)
private String age;
@Max(value = 60,message = "The upper age limit cannot be exceeded60岁" ,groups = AgeGroup.class)
private String retireAge;
}
3️⃣开启分组校验
- @Validated(NameGroup.class)指定校验分组
@RequestMapping("/testGroup")
public Result testGroup(@Validated(NameGroup.class) @RequestBody Student student) {
String name = student.getName();
String nickName = student.getNickName();
String age = student.getAge();
String retireAge = student.getRetireAge();
Map<String, String> map = new HashMap<>();
map.put("name", name);
map.put("nickname", nickName);
map.put("age", age);
map.put("retireAge", retireAge);
return Result.ok(map);
}
- ️ Test packet check:http://localhost:8080/testGroup
{
"name":"",
"nickName":"",
"age":"17",
"retireAge":"66"
}
- ️ 错误信息
{
"code": 500,
"msg": "数据校验出现问题",
"data": {
"nickName": "Nickname cannot be empty",
"name": "姓名不能为空"
}
}
- @Validated(AgeGroup.class)指定校验分组
@RequestMapping("/testGroup")
public Result testGroup(@Validated(AgeGroup.class) @RequestBody Student student) {
String name = student.getName();
String nickName = student.getNickName();
String age = student.getAge();
String retireAge = student.getRetireAge();
Map<String, String> map = new HashMap<>();
map.put("name", name);
map.put("nickname", nickName);
map.put("age", age);
map.put("retireAge", retireAge);
return Result.ok(map);
}
- ️ Test packet check:http://localhost:8080/testGroup
{
"name":"",
"nickName":"",
"age":"17",
"retireAge":66
}
- ️ 错误信息
{
"code": 500,
"msg": "数据校验出现问题",
"data": {
"retireAge": "The upper age limit cannot be exceeded60岁",
"age": "The minimum age limit cannot be lower18岁"
}
}
JSR303自定义校验
1️⃣编写自定义的校验注解
- 比如要创建一个:@ListValue 注解,Annotated field values can only be :0或1
@Documented
@Target({
METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
// 使用该属性去Validation.properties中取
String message() default "{com.atguigu.common.valid.ListValue.message}";
Class<?>[] groups() default {
};
Class<? extends Payload>[] payload() default {
};
int[] value() default {
};
}
- 设置错误信息:创建文件ValidationMessages.properties
com.firefly.common.valid.ListValue.message=必须提交指定的值 [0,1]
2️⃣编写自定义的校验器
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
/** * @author Michale @EMail:[email protected] * @Date: 2022/1/8 19:23 * @Name ListValueConstraintValidator * @Description: */
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation) {
//Get the values allowed by the annotation
int[] value = constraintAnnotation.value();
for (int i : value) {
set.add(i);
}
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
//Determines whether the incoming value satisfies the allowed value
boolean b = set.contains(value);
return b;
}
}
3️⃣关联校验器和校验注解
- 在@ListValueAnnotation association validator
@Constraint(validatedBy = {
ListValueConstraintValidator.class})
一个校验注解可以匹配多个校验器
4️⃣Add custom validation annotations
@ListValue(value = {
0,1},groups = {
AgeGroup.class,MyJRS303Group.class})
private Integer gender;
- ️ Test custom validators:http://localhost:8080/testGroup
{
"gender":"3"
}
{
"code": 500,
"msg": "数据校验出现问题",
"data": {
"gender": "必须提交指定的值 [0,1]"
}
}
边栏推荐
- 【latex异常和错误】Missing $ inserted.<inserted text>You can‘t use \spacefactor in math mode.输出文本要注意特殊字符的转义
- golang fork 进程的三种方式
- NTT的Another Me技术助力创造歌舞伎演员中村狮童的数字孪生体,将在 “Cho Kabuki 2022 Powered by NTT”舞台剧中首次亮相
- 无服务器+域名也能搭建个人博客?真的,而且很快
- MySQL使用GROUP BY 分组查询时,SELECT 查询字段包含非分组字段
- 4.1-支持向量机
- 1051 Multiplication of Complex Numbers (15 points)
- How do you optimize the performance of your Unity project?
- 【推荐系统】:协同过滤和基于内容过滤概述
- LeetCode brushing series -- 46. Full arrangement
猜你喜欢

Redis source code: how to view the Redis source code, the order of viewing the Redis source code, the sequence of the source code from the external data structure of Redis to the internal data structu

项目2-年收入判断

如何选择专业、安全、高性能的远程控制软件

TF通过feature与label生成(特征,标签)集合,tf.data.Dataset.from_tensor_slices

公牛10-11德里克·罗斯最强赛季记录

基于FPGA的FIR滤波器的实现(5)— 并行结构FIR滤波器的FPGA代码实现

1076 Wifi密码 (15 分)

1051 Multiplication of Complex Numbers (15 points)

Redis源码:Redis源码怎么查看、Redis源码查看顺序、Redis外部数据结构到Redis内部数据结构查看源码顺序
![[Recommender System]: Overview of Collaborative Filtering and Content-Based Filtering](/img/bc/fd2b8282269f460f4be2da78b84c22.png)
[Recommender System]: Overview of Collaborative Filtering and Content-Based Filtering
随机推荐
Waldom Electronics宣布成立顾问委员会
无服务器+域名也能搭建个人博客?真的,而且很快
C语言每日一练——Day02:求最小公倍数(3种方法)
伦敦银规则有哪些?
网络电话软件或迎整顿 “免费”通话须迈安全关
break pad源码编译--参考大佬博客的总结
What are the things that should be planned from the beginning when developing a project with Unity?How to avoid a huge pit in the later stage?
1046 划拳 (15 分)
1081 检查密码 (15 分)
数仓开发知识总结
基于FPGA的FIR滤波器的实现(4)— 串行结构FIR滤波器的FPGA代码实现
Activity的四种启动模式
【Pytorch】nn.PixelShuffle
易观分析联合中小银行联盟发布海南数字经济指数,敬请期待!
LeetCode brushing series -- 46. Full arrangement
测试用例很难?有手就行
Shell:三剑客之awk
项目1-PM2.5预测
js判断图片是否存在
TF中的条件语句;where()