自定义注解实现接口入参字段值校验
使用的类javax.validation
导入的包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>xxxx.RELEASE</version>
</dependency>
通过springboot的其他包依赖hibernate-validator
,一般是spring-boot-starter-web
或者单独导入spring-boot-starter-validation
也可以。不能单独导入hibernate-validator
,会报错。org.hibernate.validator.internal.constraintvalidators.bv.number.bound.AbstractMinValidator
实现类
自定义校验类
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import com.haier.boot.valid.enums.FieldDataRange;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;
/**
* ValidListEnum: 校验的注解
* Object:校验对象属性类型 Object表示所有类型都可以
*/
public class FieldDataValidator implements ConstraintValidator<FieldDataRange, Object> {
private List<String> range = null;
@Override
public void initialize(FieldDataRange constraintAnnotation) {
String[] rangeStr = constraintAnnotation.range();
if (rangeStr.length > 0) {
this.range = ListUtil.toList(rangeStr);
}
}
/**
* obj 调接口时传的实参
*/
@Override
public boolean isValid(Object obj, ConstraintValidatorContext constraintValidatorContext) {
if (obj == null || CollectionUtil.isEmpty(range)) {
return true;
}
return range.contains(Convert.toStr(obj));
}
}
自定义注解
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({METHOD, FIELD})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = FieldDataValidator.class)
public @interface FieldDataRange {
/**
* @return class containing enum values to which this String should match
*/
String range() default "";
/**
* @return the error message template
*/
String message() default "不在定义的数据范围";
/**
* @return the groups the constraint belongs to
*/
Class<?>[] groups() default {};
// 负载
Class<? extends Payload>[] payload() default {};
}
全局异常处理(获取所有校验不通过的参数)
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public String methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
log.error("入参异常", e);
BindingResult bindingResult = e.getBindingResult();
StringBuilder errMsgStringBuilder = new StringBuilder("参数校验失败:");
for (FieldError fieldError : bindingResult.getFieldErrors()) {
errMsgStringBuilder.append(String.format("%s.%n", fieldError.getDefaultMessage()));
}
return errMsgStringBuilder.toString();
}
}
测试
实体类
import com.haier.boot.valid.enums.FieldDataRange;
import lombok.Data;
@Data
public class Person {
@FieldDataRange(range = "1,2,3", message = "username取值范围1,2,3")
private String username;
@FieldDataRange(range = "1,2,3", message = "age取值范围1,2,3")
private Integer age;
@FieldDataRange(range = "1,2,3", message = "age3取值范围1,2,3")
private Long age3;
private String password;
}
接口
import javax.validation.Valid;
@PostMapping("/export/list/testUser")
public void testUser(@RequestBody @Valid Person testUser) {
helloWorldService.testUser(testUser);
}
纸上得来终觉浅,绝知此事要躬行。