如何解决在DTO级别的基于注释的验证发生在字段级别验证例如@NotNull @Size等之前
我有一个DTO类,在该类中,一些字段是必填项。 并且,基于另一个可以假定值A和B的类型字段 如果是A型,则只需检查1个项目即可通过;如果是B型,也可以大于1个。
我需要检查列表在DTO类级别中是否至少具有1个值。而且,在自定义批注验证中,我需要根据DTO的类型字段检查列表的大小。
所以,在DTO中
@NotNull
@Size(min = 1)
private List<@NotBlank String> items;
而且,在内部注释
if (cancelType == CancellationTypeEnum.A && cancelDto.getItems().size() > 1) {
isValid = false;
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(
"Only one item can be sent for 'A' cancel type.").addConstraintViolation();
}
但是,由于字段级别是稍后发生的,如果我为items字段传递null,则它将转到此批注验证器并由于field为null且我要获取大小而抛出NPE
临时解决方案是我先执行null检查,然后检查大小,但是无论如何在字段级别我们都提供@NotNull。
是否有任何方法可以执行类级别的自定义批注,以在发生字段级别验证之后进行验证。 在这种情况下,由于字段为null且不会转到自定义类级别注释,它将引发字段级别验证
解决方法
您可以结合使用来自文档的JS-303验证组(请参见here)和@Validated:
JSR-303 Valid的变体,支持验证规范 组。
例如:
@CheckEnumSize(groups = {Secondary.class})
public class CancelDto {
public CancelDto(List<String> items) {
this.items = items;
}
@NotNull(groups = {Primary.class})
@Size(min = 1)
public List<@NotNull String> items;
public CancellationTypeEnum cancelType;
public List<String> getItems() {
return items;
}
}
其中Primary
是一个简单的界面:
public interface Primary {
}
与Secondary
相同:
public interface Secondary {
}
最后,您可以使用经过验证的方式:
@Service
@Validated({Primary.class,Secondary.class})
public class CancelService {
public void applyCancel(@Valid CancelDto cancel) {
//TODO
}
}
在将以上代码与项目为空的CancelDto
一起使用时,您应该获得:
Caused by: javax.validation.ConstraintViolationException: applyCancel.cancel.items: must not be null
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。