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

lfapxunr  于 2024-01-05  发布在  Java
关注(0)|答案(3)|浏览(190)

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

  1. class VehicleDto {
  2. private String type;
  3. private Car car;
  4. private Bike bike;
  5. }

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

cgyqldqp

cgyqldqp1#

在类中有两个字段,而其中只有一个可以呈现,对我来说似乎是一种设计气味。但是如果你坚持这样的设计-你可以为你的VehicleDto类创建一个自定义的Validator

  1. public class VehicleValidator implements Validator {
  2. public boolean supports(Class clazz) {
  3. return VehicleDto.class.equals(clazz);
  4. }
  5. public void validate(Object obj, Errors errors) {
  6. VehicleDto dto = (VehicleDto) obj;
  7. ValidationUtils.rejectIfEmptyOrWhitespace(errors, "type",
  8. "error.message.for.type.field");
  9. if (null != dto.getType()
  10. && null != dto.getCar()
  11. && null != dto.getBike()) {
  12. switch(dto.getType()) {
  13. case "car":
  14. errors.rejectValue("bike", "error.message.for.bike.field");
  15. break;
  16. case "bike":
  17. errors.rejectValue("car", "error.message.for.car.field");
  18. break;
  19. }
  20. }
  21. }
  22. }

字符串
另外,请参阅Spring文档中关于验证的内容:

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

mnemlml82#

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

pom.xml中的依赖项:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-validation</artifactId>
  4. </dependency>

字符串

DTO类:

  1. @ValidTaskDTO
  2. public class TaskDTO {
  3. @FutureOrPresent
  4. private ZonedDateTime dueDate;
  5. @NotBlank(message = "Title cannot be null or blank")
  6. private String title;
  7. private String description;
  8. @NotNull
  9. private RecurrenceType recurrenceType;
  10. @Future
  11. private ZonedDateTime repeatUntil;
  12. }

自定义标注:

  1. @Constraint(validatedBy = {TaskDTOValidator.class})
  2. @Target({ElementType.TYPE})
  3. @Retention(RetentionPolicy.RUNTIME)
  4. public @interface ValidTaskDTO {
  5. String message() default "Due date should not be greater than or equal to Repeat Until Date.";
  6. Class<?>[] groups() default {};
  7. Class<? extends Payload>[] payload() default {};
  8. }

约束验证器:

  1. public class TaskDTOValidator implements ConstraintValidator<ValidTaskDTO, TaskDTO> {
  2. @Override
  3. public void initialize(ValidTaskDTO constraintAnnotation) {
  4. }
  5. @Override
  6. public boolean isValid(TaskDTO taskDTO, ConstraintValidatorContext constraintValidatorContext) {
  7. if (taskDTO.getRecurrenceType() == RecurrenceType.NONE) {
  8. return true;
  9. }
  10. return taskDTO.getRepeatUntil() != null && taskDTO.getDueDate().isBefore(taskDTO.getRepeatUntil());
  11. }
  12. }


确保在RestController中的postmapping方法的RequestBody前面有@Valid。只有这样验证才会被调用:

  1. @PostMapping
  2. public TaskReadDTO createTask(@Valid @RequestBody TaskDTO taskDTO) {
  3. .....
  4. }


我希望这对你有帮助。如果你需要关于步骤的详细解释,请看this video

展开查看全部
w6mmgewl

w6mmgewl3#

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

  1. public static class VehicleDto {
  2. private String type;
  3. private Car car;
  4. private Bike bike;
  5. @AssertTrue(message = "You must inform either car or bike, but not both")
  6. private boolean isValidVehicle() {
  7. return (car != null && bike == null) || (car == null && bike != null);
  8. }
  9. }

字符串

相关问题