【问题标题】:Spring boot 2 rest validator called twice when groups are used使用组时,Spring boot 2 休息验证器被调用两次
【发布时间】:2019-08-12 20:08:25
【问题描述】:

当我在 Rest 控制器的类级别启用 @Validated spring 注释时,会生成 2 个验证上下文(每个都有不同的前缀)。 @Validated 注释是必需的,因为我想使用 2 个不同的验证组,但由于有 2 个验证上下文,所有验证都会执行两次。我认为所有验证都应该只验证一次:

  • 我的配置有问题吗?
  • 我错过了什么吗?
    @RestController
    @RequestMapping
    @Validated
    public class KidController {
        private final KidService kidService;

        public KidController(KidService kidService) {
            this.kidService = kidService;
        }

        @PostMapping
        @Validated(OnRegistrationRequest.class)
        @ResponseStatus(HttpStatus.CREATED)
        public KidDTO createKidRegistration(@RequestBody @Valid KidDTO kid) {
            return kidService.saveKid(kid);
        }
    }

    public interface KidValidatorGroup {
        interface OnRegistrationRequest extends Default {
        }

        interface OnCheckInPersist extends Default {
        }
    }


    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonPropertyOrder({"id"})
    @JsonInclude(Include.NON_NULL)
    public class KidDTO {
        @NotEmpty
        private String id;
        @NotEmpty
        private String firstName;
        @KidAgeConstraint
        private Integer age;
        @NotEmpty(groups = OnCheckInPersist.class)
        private String roomDocId;
        @Valid
        private Set<AnswerDTO> answers;
        @Valid
        private Set<GuardianDTO> guardians;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @FieldStrictDependentConstraint(principalField = "answer", 
       dependentField = "description")
    @JsonInclude(Include.NON_NULL)
    public class AnswerDTO {
        @QuestionIdConstraint(groups = OnRegistrationRequest.class)
        private String questionId;
    }

我在调试应用程序时发现了 2 个上下文,而第二个上下文看起来像前缀这样的方法名称。

【问题讨论】:

标签: java spring spring-boot bean-validation spring-restcontroller


【解决方案1】:

在您的代码中,您有一个注释会触发方法参数和方法返回值的验证:

    @PostMapping
    @Validated(OnRegistrationRequest.class) // this one is "@Valid" with a specified group and will be used for return value validation
    @ResponseStatus(HttpStatus.CREATED)
    public KidDTO createKidRegistration(@RequestBody @Valid /* this one is for method parameter */ KidDTO kid) {
        return kidService.saveKid(kid);
    }

查看屏幕截图中的不同路径。一个是createKidRegistration.kid.firstName,这是一个参数。如果您只需要使用特定组验证传递的参数,则应尝试将@Valid 替换为@Validated(OnRegistrationRequest.class),并从方法级别完全删除@Validated

【讨论】:

    猜你喜欢
    • 2019-02-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 1970-01-01
    • 2019-11-19
    • 2019-08-15
    相关资源
    最近更新 更多