Spring-boot-两个相关字段的自定义验证

时间:2019-12-10 08:08:02

标签: java spring-boot spring-data-jpa

@Column(length = 100)
private String post;

@NotNull
@Column
private String name;

我如何实现验证

  • 如果帖子为空或为空,则不得接受姓名

有什么主意我可以从这个开始吗?

2 个答案:

答案 0 :(得分:2)

您必须创建一个类级别约束。

  1. 创建注释
  2. 创建一个ConstraintValidator

这是文档中的一个示例:https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-class-level-constraints

包org.hibernate.validator.referenceguide.chapter06.classlevel;

注释:

@Target({ TYPE, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = { ValidPassengerCountValidator.class })
@Documented
public @interface ValidPassengerCount {

    String message() default "{org.hibernate.validator.referenceguide.chapter06.classlevel." +
            "ValidPassengerCount.message}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

验证者

package org.hibernate.validator.referenceguide.chapter06.classlevel;

public class ValidPassengerCountValidator
        implements ConstraintValidator<ValidPassengerCount, Car> {

    @Override
    public void initialize(ValidPassengerCount constraintAnnotation) {
    }

    @Override
    public boolean isValid(Car car, ConstraintValidatorContext context) {
        if ( car == null ) {
            return true;
        }

        return car.getPassengers().size() <= car.getSeatCount();
    }
}

然后您可以在课程级别使用注释:

包org.hibernate.validator.referenceguide.chapter02.classlevel;

@ValidPassengerCount
public class Car {

    private int seatCount;

    private List<Person> passengers;

    //...
}

答案 1 :(得分:2)

例如,如果我们要检查一个 DTO 对象是否有效,通过比较它的两个属性 dueDaterepeatUntil ,以下是实现它的步骤。如果您需要有关步骤的详细说明,请查看 this video

在 pom.xml 中的依赖:

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

DTO 类:

@ValidTaskDTO
public class TaskDTO {

    @FutureOrPresent
    private ZonedDateTime dueDate;

    @NotBlank(message = "Title cannot be null or blank")
    private String title;

    private String description;

    @NotNull
    private RecurrenceType recurrenceType;

    @Future
    private ZonedDateTime repeatUntil;

}

自定义注解:

@Constraint(validatedBy = {TaskDTOValidator.class})
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidTaskDTO {
    String message() default "Due date should not be greater than or equal to Repeat Until Date.";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

约束验证器:

public class TaskDTOValidator implements ConstraintValidator<ValidTaskDTO, TaskDTO> {
    @Override
    public void initialize(ValidTaskDTO constraintAnnotation) {

    }

    @Override
    public boolean isValid(TaskDTO taskDTO, ConstraintValidatorContext constraintValidatorContext) {
        if (taskDTO.getRecurrenceType() == RecurrenceType.NONE) {
            return true;
        }

        return taskDTO.getRepeatUntil() != null && taskDTO.getDueDate().isBefore(taskDTO.getRepeatUntil());
    }
}

确保您在 RestController 中的 postmapping 方法的 RequestBody 前面有 @Valid。只有这样验证才会被调用:

@PostMapping
public TaskReadDTO createTask(@Valid @RequestBody TaskDTO taskDTO) {
.....
}