Spring boot 2 rest 验证器在使用组时调用两次
Spring boot 2 rest validator called twice when groups are used
当我在 Rest 控制器的 class 级别启用 @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 个上下文,第二个上下文的方法名称类似于前缀。
在您的代码中,您有一个注解可以触发对方法参数和方法的验证 return 值:
@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
。
当我在 Rest 控制器的 class 级别启用 @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 个上下文,第二个上下文的方法名称类似于前缀。
在您的代码中,您有一个注解可以触发对方法参数和方法的验证 return 值:
@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
。