自定义注解实现接口入参字段值校验

使用的类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);
}
posted @ 2024-01-15 14:04  品书读茶  阅读(59)  评论(0编辑  收藏  举报