多个 ConstraintValidator 的实现及其优先级(enable/disable by requests endpoint)
Implementatio of mutliple ConstraintValidator and their priority (enable/disable by requests endpoint)
假设我有一个包含两个应验证字段的对象:
public class AnyRQ {
@MerchantAccountValidation
@JsonProperty(value = "merchant-account")
private MerchantAccount merchantAccount;
@RequestIdValidation
@JsonProperty(value = "request-id")
private String requestId;
}
注释 @MerchantAccountValidation
和 @RequestIdValidation
都实现了 ConstraintValidator
并包含了有效或无效的规则。 (只显示一个class)
public class RequestIdValidator
implements ConstraintValidator<RequestIdValidation, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return value != null && value.length() > 10;
}
}
现在我有一个带有两个端点的控制器。端点 1 应验证两个字段,但请求 2 应仅验证 requestId
.
@RestController
@RequestMapping("/validate")
public class ValidController {
@PostMapping("/endpoint1")
public ResponseEntity<?> register(@Valid @RequestBody AnyRQ req, Errors errors) {
if (errors.hasErrors()) {
}
return null;
}
@PostMapping("/endpoint2")
public ResponseEntity<?> authorization(@Valid @RequestBody AnyRQ req, Errors errors) {
if (errors.hasErrors()) {
}
return null;
}
}
有什么方法可以实现某种优先级或继承来使它正常工作吗?我正在考虑在端点的方法级别上使用验证注释。但不幸的是,这不起作用。
帕特里克!
要达到预期的结果,您可以使用@GroupSequence。它主要用于排序验证(如果 id 为 null f.e,则无需检查数据库中是否存在实体),但可以完成您的任务。
假设您有 2 个验证组(需要更好的名称 :)):
public interface InitialValidation {
}
@GroupSequence(InitialValidation.class)
public interface InitialValidationGroup {
}
public interface FullValidation {
}
@GroupSequence(FullValidation.class)
public interface FullValidationGroup {
}
在 DTO 中指定它们:
public class AnyRQ {
@MerchantAccountValidation(groups = FullValidation.class)
@JsonProperty(value = "merchant-account")
private MerchantAccount merchantAccount;
@RequestIdValidation(groups = {InitialValidation.class, FullValidation.class})
@JsonProperty(value = "request-id")
private String requestId;
}
并且在controller中使用@Validated代替@Valid来提供对应的组:
@RestController
@RequestMapping("/验证")
public class 有效控制器 {
@PostMapping("/endpoint1")
public ResponseEntity<?> register(@Validated(FullValidationGroup.class) @RequestBody AnyRQ req, Errors errors) {
if (errors.hasErrors()) {
}
return null;
}
@PostMapping("/endpoint2")
public ResponseEntity<?> authorization(@Validated(InitialValidationGroup.class) @RequestBody AnyRQ req, Errors errors) {
if (errors.hasErrors()) {
}
return null;
}
}
另一种选择是在 DTO 中保留一组,但在控制器中为 @Validated 指定两组。
假设我有一个包含两个应验证字段的对象:
public class AnyRQ {
@MerchantAccountValidation
@JsonProperty(value = "merchant-account")
private MerchantAccount merchantAccount;
@RequestIdValidation
@JsonProperty(value = "request-id")
private String requestId;
}
注释 @MerchantAccountValidation
和 @RequestIdValidation
都实现了 ConstraintValidator
并包含了有效或无效的规则。 (只显示一个class)
public class RequestIdValidator
implements ConstraintValidator<RequestIdValidation, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return value != null && value.length() > 10;
}
}
现在我有一个带有两个端点的控制器。端点 1 应验证两个字段,但请求 2 应仅验证 requestId
.
@RestController
@RequestMapping("/validate")
public class ValidController {
@PostMapping("/endpoint1")
public ResponseEntity<?> register(@Valid @RequestBody AnyRQ req, Errors errors) {
if (errors.hasErrors()) {
}
return null;
}
@PostMapping("/endpoint2")
public ResponseEntity<?> authorization(@Valid @RequestBody AnyRQ req, Errors errors) {
if (errors.hasErrors()) {
}
return null;
}
}
有什么方法可以实现某种优先级或继承来使它正常工作吗?我正在考虑在端点的方法级别上使用验证注释。但不幸的是,这不起作用。
帕特里克!
要达到预期的结果,您可以使用@GroupSequence。它主要用于排序验证(如果 id 为 null f.e,则无需检查数据库中是否存在实体),但可以完成您的任务。 假设您有 2 个验证组(需要更好的名称 :)):
public interface InitialValidation {
}
@GroupSequence(InitialValidation.class)
public interface InitialValidationGroup {
}
public interface FullValidation {
}
@GroupSequence(FullValidation.class)
public interface FullValidationGroup {
}
在 DTO 中指定它们:
public class AnyRQ {
@MerchantAccountValidation(groups = FullValidation.class)
@JsonProperty(value = "merchant-account")
private MerchantAccount merchantAccount;
@RequestIdValidation(groups = {InitialValidation.class, FullValidation.class})
@JsonProperty(value = "request-id")
private String requestId;
}
并且在controller中使用@Validated代替@Valid来提供对应的组:
@RestController
@RequestMapping("/验证") public class 有效控制器 {
@PostMapping("/endpoint1")
public ResponseEntity<?> register(@Validated(FullValidationGroup.class) @RequestBody AnyRQ req, Errors errors) {
if (errors.hasErrors()) {
}
return null;
}
@PostMapping("/endpoint2")
public ResponseEntity<?> authorization(@Validated(InitialValidationGroup.class) @RequestBody AnyRQ req, Errors errors) {
if (errors.hasErrors()) {
}
return null;
}
}
另一种选择是在 DTO 中保留一组,但在控制器中为 @Validated 指定两组。