Java 验证dto spring boot中三个字段中的至少一个
我有一个DTO,看起来像这样: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
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在这里问了另一个问题:对于这种情况,理想的设计应该是什么?为设计问题添加了一个新问题: