我有一个看起来像这样的DTO:
class VehicleDto {
private String type;
private Car car;
private Bike bike;
}
现在根据类型,我需要至少验证Car和Bike中的一个。
两者都不能出现在同一个请求中。
我该怎么做?
答案 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
对象是否有效,通过比较它的两个属性 dueDate
和 repeatUntil
,以下是实现它的步骤。
在 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