Spring Boot 自定义验证 jsr 303 不工作

Springboot custom validation jsr 303 is not working

我试图在年龄字段上添加自定义注释验证。因为我看到了一些 JSR 303 主题

控制器

@Validated
@Controller
public class StudentController {

    @Autowired
    private StudentRepository repository;

    @PostMapping("/send")
    public ResponseEntity saveStudent(@AgeValidator @RequestBody Student student) {
        System.out.println("saveStudent invoked");
        repository.save(student);
        ResponseData responseData = new ResponseData();
        responseData.setResultId("result");
        responseData.setResultValue("saved");
        ResponseEntity entity = new ResponseEntity(responseData, HttpStatus.OK);
        return entity;
    }
}

型号

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    @Id
    @Column(length = 7)
    private String Id;
    private String fullName;
    private Integer age;
    private String department;

}

年龄验证器

package com.example.demo4;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Documented
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AgeValidatorImpl.class)
public @interface AgeValidator {
    String message()
            default "Please enter a valid age";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

AgeValidatorImpl

class AgeValidatorImpl implements ConstraintValidator<AgeValidator, Student> {

    @Override
    public void initialize(AgeValidator constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean isValid(Student t, ConstraintValidatorContext cvc) {
        System.out.println("AgeValidatorImpl invoked");
        if (t.getAge() < 18) {
            return false;
        } else if (t.getAge() > 40) {
            return false;
        }
        return true;
    }
}

因此,如果我在任何年龄使用邮递员发送,它都会保存记录并且不会验证。我看到很多人评论要在我从 import org.springframework.validation.annotation.Validated 导入的控制器 @validated 上添加注释。仍然为什么这不起作用。缺少什么?

你可以试试这个,

我已经更新了 @Age 注释。您可以提供验证的上限和下限。请注意,我已将 ElementType.FIELD 添加到 @Target。它也允许您在 class 字段中使用它。

@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AgeValidator.class)
public @interface Age {
    int lower() default 14;
    int upper() default 60;
    String message() default "Please enter a valid age";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

这是注释的验证约束。

public class AgeValidator implements ConstraintValidator<Age, Integer> {

    private int upperLimit;
    private int lowerLimit;

    @Override
    public boolean isValid(Integer i, ConstraintValidatorContext constraintValidatorContext) {
        return lowerLimit < i && i < upperLimit;
    }

    @Override
    public void initialize(Age constraintAnnotation) {
        this.lowerLimit = constraintAnnotation.lower();
        this.upperLimit = constraintAnnotation.upper();
    }
}

可以将注解传给class个字段,覆盖上下限。

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    @Id
    @Column(length = 7)
    private String Id;
    private String fullName;
    @Age(lower = 10, upper = 70)
    private Integer age;
    private String department;

}

使用 @Validated 注释根据所有验证约束验证 Student 对象。

@PostMapping("/send")
    public ResponseEntity saveStudent(@Validated @RequestBody Student student)

更新

替换这个依赖,

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
    <type>jar</type>
</dependency>

由此

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>