SpringBoot自定义注解验证枚举
SpringBoot自定义注解验证枚举
业务场景:数据校验,需要对枚举类型的数据传参,进行数据校验,不能随便传参。
1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2、创建注解类
package com.shier.valid;
import com.shier.validator.EnumValueValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* @author cys
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {EnumValueValidator.class})
public @interface EnumValue {
// 默认错误消息
String message() default "必须为指定值";
// 字符串类型
String[] strValues() default {};
// 整型
int[] intValues() default {};
// 分组
Class<?>[] groups() default {};
// 负载
Class<? extends Payload>[] payload() default {};
// 忽略null, 为true时,参数传null不检验
boolean ignoreNull() default false;
;
// 指定多个时使用
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
EnumValue[] value();
}
}
3、创建自定义检验器类
package com.shier.validator;
import com.shier.valid.EnumValue;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Objects;
/**
* @author cys
*/
public class EnumValueValidator implements ConstraintValidator<EnumValue, Object> {
private String[] strValues;
private int[] intValues;
private boolean ignoreNull;
@Override
public void initialize(EnumValue constraintAnnotation) {
this.strValues = constraintAnnotation.strValues();
this.intValues = constraintAnnotation.intValues();
this.ignoreNull = constraintAnnotation.ignoreNull();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
if (Objects.isNull(value) && this.ignoreNull) {
return true;
}
if (value instanceof String) {
for (String s : strValues) {
if (s.equals(value)) {
return true;
}
}
} else if (value instanceof Integer) {
for (Integer s : intValues) {
if (s == value) {
return true;
}
}
}
return false;
}
}
4、创建请求类
package com.shier.controller;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.shier.valid.EnumValue;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @author shier
* @date 2023年01月12日
*/
@Data
public class OrderReq {
private Long orderId;
@EnumValue(intValues = {1,2,3,4}, message = "订单状态必须为指定值,1-新建 2-已支付 3-已完成 4-已取消",ignoreNull = true)
private Integer orderStatus;
/**
* JsonFormat: 可以把日期类型转成指定格式输出
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
private Date updateTime;
}
5、测试类
package com.shier.controller;
import com.shier.req.OrderReq;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @author shier
* @date 2023年01月12日
*/
@RestController
public class TestController {
@GetMapping("/test")
public OrderReq test(@RequestBody @Valid OrderReq orderReq) {
orderReq.setCreateTime(LocalDateTime.now());
orderReq.setUpdateTime(new Date());
return orderReq;
}
}
6、启动测试
因为在OrderReq类中的orderStatus字段添加了注解规定值在1、2、3、4。如果传入其他值会提示异样, 这里因为没有统一异常处理, 才会没有提示自定义的信息