我有一个DTO,看起来像这样:
class VehicleDto { private String type; private Car car; private Bike bike;}
class VehicleDto {
private String type;
private Car car;
private Bike bike;
}
字符串现在,根据类型,我需要验证至少一个汽车和自行车。两者不能出现在同一个请求中。我该怎么做?
cgyqldqp1#
在类中有两个字段,而其中只有一个可以呈现,对我来说似乎是一种设计气味。但是如果你坚持这样的设计-你可以为你的VehicleDto类创建一个自定义的Validator。
VehicleDto
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; } } }}
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");
字符串另外,请参阅Spring文档中关于验证的内容:
mnemlml82#
例如,如果我们想检查TaskDTO对象是否有效,通过比较它的两个属性dueDate和repeatUntil,下面是实现它的步骤。
TaskDTO
dueDate
repeatUntil
pom.xml中的依赖项:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId></dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
字符串
DTO类:
@ValidTaskDTOpublic 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;}
@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 {};}
@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()); }}
public class TaskDTOValidator implements ConstraintValidator<ValidTaskDTO, TaskDTO> {
@Override
public void initialize(ValidTaskDTO constraintAnnotation) {
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。只有这样验证才会被调用:
@Valid
@PostMappingpublic TaskReadDTO createTask(@Valid @RequestBody TaskDTO taskDTO) {.....}
@PostMapping
public TaskReadDTO createTask(@Valid @RequestBody TaskDTO taskDTO) {
.....
型我希望这对你有帮助。如果你需要关于步骤的详细解释,请看this video
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); }}
public static class VehicleDto {
@AssertTrue(message = "You must inform either car or bike, but not both")
private boolean isValidVehicle() {
return (car != null && bike == null) || (car == null && bike != null);
3条答案
按热度按时间cgyqldqp1#
在类中有两个字段,而其中只有一个可以呈现,对我来说似乎是一种设计气味。但是如果你坚持这样的设计-你可以为你的
VehicleDto
类创建一个自定义的Validator。字符串
另外,请参阅Spring文档中关于验证的内容:
mnemlml82#
例如,如果我们想检查
TaskDTO
对象是否有效,通过比较它的两个属性dueDate
和repeatUntil
,下面是实现它的步骤。pom.xml中的依赖项:
字符串
DTO类:
型
自定义标注:
型
约束验证器:
型
确保在RestController中的postmapping方法的RequestBody前面有
@Valid
。只有这样验证才会被调用:型
我希望这对你有帮助。如果你需要关于步骤的详细解释,请看this video
w6mmgewl3#
如果使用spring-boot-starter-validation,可以像
字符串