在dto spring boot中验证三个字段中的至少一个

时间:2017-09-19 11:23:36

标签: java spring spring-boot

我有一个看起来像这样的DTO:

class VehicleDto {
    private String type;
    private Car car;
    private Bike bike;
}

现在根据类型,我需要至少验证Car和Bike中的一个。

两者都不能出现在同一个请求中。

我该怎么做?

2 个答案:

答案 0 :(得分:5)

在课堂上有两个领域,而其中只有一个可以出现,对我来说似乎是一种设计气味。 但是,如果您坚持这样的设计 - 您可以为VehicleDto课程创建自定义Validator

public class VehicleValidator implements Validator {

    public boolean supports(Class clazz) {
        return VehicleDto.class.equals(clazz);
    }

    public void validate(Object obj, Errors errors) {

        VehicleDto dto = (VehicleDto) obj;

        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "type",
                                    "error.message.for.type.field");

        if (null != dto.getType()
              && null != dto.getCar()
              && null != dto.getBike()) {
            switch(dto.getType()) {
                case "car":
                    errors.rejectValue("bike", "error.message.for.bike.field");
                    break;
                case "bike":
                    errors.rejectValue("car", "error.message.for.car.field");
                    break;
            }
        }
    }
}

另外,请参阅有关验证的Spring文档:

答案 1 :(得分:0)

例如,如果我们要检查我的 TaskDTO 对象是否有效,通过比较它的两个属性 dueDaterepeatUntil,以下是实现它的步骤。

在 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) {
.....
}

我希望这会有所帮助。如果您需要有关步骤的详细说明,请查看 this video