java 在dto spring Boot 中至少选择三个字段之一

lfapxunr  于 5个月前  发布在  Java
关注(0)|答案(3)|浏览(50)

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

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

字符串
现在,根据类型,我需要验证至少一个汽车和自行车。
两者不能出现在同一个请求中。
我该怎么做?

cgyqldqp

cgyqldqp1#

在类中有两个字段,而其中只有一个可以呈现,对我来说似乎是一种设计气味。但是如果你坚持这样的设计-你可以为你的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文档中关于验证的内容:

  • 使用Spring的Validator接口进行验证
  • 将代码解析为错误消息
  • 注入验证程序
mnemlml8

mnemlml82#

例如,如果我们想检查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

w6mmgewl

w6mmgewl3#

如果使用spring-boot-starter-validation,可以像

public static class VehicleDto {
    private String type;
    private Car car;
    private Bike bike;

    @AssertTrue(message = "You must inform either car or bike, but not both")
    private boolean isValidVehicle() {
        return (car != null && bike == null) || (car == null && bike != null);
    }
}

字符串

相关问题