CodeArena

Java数据校验

2023-04-13
Java
最后更新:2024-05-23
3分钟
580字

Maven依赖

1
<dependency>
2
<groupId>org.hibernate.validator</groupId>
3
<artifactId>hibernate-validator</artifactId>
4
<version>6.2.3.Final</version>
5
</dependency>

分组校验

当对同一个字段在不同情况下(不同方法)需要有不同的校验规则时,可以使用分组校验。

比如新增商品时禁止携带商品 id,需要使用 @Null 注解, 但是修改商品时必须携带商品 id,需要使用 @NotNull注解。

校验注解中一般都有 groups 属性:

1
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
2
@Retention(RUNTIME)
3
@Repeatable(List.class)
4
@Documented
5
@Constraint(validatedBy = { })
6
public @interface Null {
7
8
String message() default "{javax.validation.constraints.Null.message}";
9
10
Class<?>[] groups() default { };
11
12
Class<? extends Payload>[] payload() default { };
13
14
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
15
@Retention(RUNTIME)
6 collapsed lines
16
@Documented
17
@interface List {
18
19
Null[] value();
20
}
21
}

可以设置 id 的校验注解如下:

1
@Null(message = "添加不能指定id", groups = {SaveGroup.class})
2
@NotNull(message = "修改需要指定id", groups = {UpdateGroup.class})
3
@TableId
4
private Long id;

其中 SaveGroupUpdateGroup 只是两个作为标识的接口

Controller层:

1
@RestController
2
public class GoodsController{
3
@RequestMapping("/save")
4
public Result save(@Validated({SaveGroup.class} @RequestBody Goods good)){
5
...
6
}
7
@RequestMapping("/update")
8
public Result update(@Validated({UpdateGroup.class} @RequestBody Goods good)){
9
...
10
}
11
}

自定义校验器

在项目中经常会遇到需要对前端传过来的参数进行校验,但是在使用正则表达式校验数值类型的字段时是不会生效的,比如下面这个案例就会报错:

1
@Pattern(regexp = "/^[0-1]$/", message="显示状态必须为0或1")
2
private Integer status;

这个时候可以使用自定义校验注解:

1
@EnumValidation(values={0,1}, group={SaveGroup.class, UpdateGroup.class})
2
private Integer status;

注解:

1
import javax.validation.Constraint;
2
import javax.validation.Payload;
3
import java.lang.annotation.Documented;
4
import java.lang.annotation.Retention;
5
import java.lang.annotation.Target;
6
7
import static java.lang.annotation.ElementType.*;
8
import static java.lang.annotation.RetentionPolicy.RUNTIME;
9
10
/**
11
* @author zql
12
* @version 1.0
13
* 自定义校验注解
14
* 1. @Constraint(validatedBy = { }) 可以指定该注解和校验器关联
15
* 2. message() default "{}" 指定返回的错误信息--ValidationMessages.properties(Unicode格式)
14 collapsed lines
16
*/
17
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
18
@Retention(RUNTIME)
19
@Documented
20
@Constraint(validatedBy = {EnumConstraintValidator.class})
21
public @interface EnumValidation {
22
String message() default "{com.njupt.valid.EnumValidation.message}";
23
24
Class<?>[] groups() default {};
25
26
Class<? extends Payload>[] payload() default {};
27
28
int[] values() default {};
29
}

需要注意的是注解的message属性值,这里填入的是 package name.EnumValidation.message,需要在Resources目录下建立ValidationMessages.properties文件,且需要转成Unicode编码格式:

1
com.njupt.valid.EnumValidation.message=\u663E\u793A\u72B6\u6001\u7684\u503C\u5FC5\u987B\u4E3A\u0030\u6216\u8005\u0031

校验器:

1
import javax.validation.ConstraintValidator;
2
import javax.validation.ConstraintValidatorContext;
3
import java.util.HashSet;
4
import java.util.Set;
5
6
/**
7
* @author 左齐亮
8
* @version 1.0
9
* 自定义校验器
10
*/
11
public class EnumConstraintValidator implements ConstraintValidator<EnumValidation, Integer> {
12
13
private Set<Integer> set = new HashSet<>();
14
15
@Override
14 collapsed lines
16
public void initialize(EnumValidation constraintAnnotation) {
17
// 获取注解传入的values
18
int[] values = constraintAnnotation.values();
19
for (int value : values) {
20
set.add(value);
21
}
22
}
23
24
@Override
25
public boolean isValid(Integer value, ConstraintValidatorContext context) {
26
// 参数value是请求携带的参数值
27
return set.contains(value);
28
}
29
}
本文标题:Java数据校验
文章作者:Echoidf
发布时间:2023-04-13
感谢大佬送来的咖啡☕
alipayQRCode
wechatQRCode