实现对入参校验逻辑,
利用@Constraint绑定实现了ConstraintValidator接口的方法
注解Check.java
package com.snail.redisMemory.annotaion;
import com.snail.redisMemory.paramcheck.CheckType;
import java.lang.annotation.*;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 常用校验 枚举
*/
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = Check.CheckValidator.class)// 注意这里,指出了自定义的校验方法
public @interface Check {
String message() default ""; // 自定义异常返回信息
CheckType type(); // 自定义校验字段
Class<?>[] groups() default {};
Class<? extends javax.validation.Payload>[] payload() default {};
/**
* 校验实现
* 实现ConstraintValidator接口,这是个泛型接口,泛型中第一个是自定义的注解,第二个是注解使用的类型。
* 这里就是我们调用的字段校验方法
*/
class CheckValidator implements ConstraintValidator<Check,Object>{
private CheckType type;
@Override
public void initialize(Check constraintAnnotation) {
this.type=constraintAnnotation.type();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
return CheckType.validate(type,value);
}
}
}
CheckType.java
package com.snail.redisMemory.paramcheck;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;
import org.springframework.util.StringUtils;
/**
* 常用校验类型
*/
public enum CheckType {
TOOLOOG_DATE("Date", "短日期格式", "yyyyMMddHHmmssSSS"),
REQUEST_NO("RequestNo", "请求流水号", "^[0-9a-zA-Z]{32}");
public String value;
public String label;
public String regular;
private CheckType(String value, String label, String regular) {
this.value = value;
this.label = label;
this.regular = regular;
}
/**
* 校验方法
* 验证传入的枚举值,是否符合规则
* @param type
* @return true:验证成功;false:验证失败
*/
public static boolean validate(CheckType type, Object obj) {
if (null == obj || null == type) {
//空不校验
return true;
}
if (!(obj instanceof String)) {
//不是String 返回false
return false;
}
String str = obj.toString();
if (StringUtils.isEmpty(str)) {
//空字符串不校验
return true;
}
//日期格式不适用正则
if ("Date".equals(type.value)) {
SimpleDateFormat sdf = new SimpleDateFormat(type.regular);
try {
sdf.parse(str);
} catch (Exception e) {
return false;
}
return true;
}
//使用正则校验
return Pattern.matches(type.regular, str);
}
}
UserDto
package com.snail.redisMemory.paramcheck;
import java.io.Serializable;
import com.snail.redisMemory.annotaion.Check;
import lombok.Data;
@SuppressWarnings("serial")
@Data
public class UserDto implements Serializable{
/**
* 编码
*/
@Check(type=CheckType.REQUEST_NO,message="编码格式错误")
private String requestNo;
@Check(type=CheckType.TOOLOOG_DATE,message="时间戳格式不正确,格式:yyyyMMddHHmmssSSS")
private String timestamp;
}
最后写post方法调用
@PostMapping("/check")
public Object test(@RequestBody @Valid UserDto user) {
return "";
}
调用结果
涉及依赖,其中若不引用hibernate-validator,不会触发校验逻辑
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.15.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>