Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 验证dto spring boot中三个字段中的至少一个_Java_Spring_Spring Boot - Fatal编程技术网

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

Java 验证dto spring boot中三个字段中的至少一个,java,spring,spring-boot,Java,Spring,Spring Boot,我有一个DTO,看起来像这样: class VehicleDto { private String type; private Car car; private Bike bike; } 现在,根据类型,我需要验证至少一辆汽车和自行车 两者不能同时存在于同一请求中 我怎样才能做到这一点呢?课堂上有两个字段,而其中只有一个字段可以显示,这对我来说似乎是一种设计的味道。 但是如果你坚持这样的设计,你可以为你的车辆创建一个定制的类 public class VehicleVa

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

class VehicleDto {
    private String type;
    private Car car;
    private Bike bike;
}
现在,根据类型,我需要验证至少一辆汽车和自行车

两者不能同时存在于同一请求中


我怎样才能做到这一点呢?

课堂上有两个字段,而其中只有一个字段可以显示,这对我来说似乎是一种设计的味道。 但是如果你坚持这样的设计,你可以为你的
车辆创建一个定制的

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文档中有关验证的内容:


例如,如果我们想通过比较我的
TaskDTO
对象的两个属性
dueDate
repeatUntil
来检查它是否有效,下面是实现它的步骤

pom.xml中的依赖关系:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
@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());
    }
}
自定义注释:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
@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());
    }
}

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

,您可以为汽车和自行车编写2个自定义验证器,将该类型考虑在内。如果两个都不能出现在同一请求中,为什么VehicleDTO同时包含这两个?最好将car和bike字段替换为一种车辆类型(由car和bike扩展的抽象类),您能为此编写一个示例代码吗?我理解你说的,但仍然不确定我是否正确。@pezetem在这里问了另一个问题:对于这种情况,理想的设计应该是什么?为设计问题添加了一个新问题: