【发布时间】:2018-12-10 22:21:58
【问题描述】:
我正在 Spring Boot 2+ 中开发一个 RESTful API,为此我需要执行多个验证。没什么特别的,只是典型的@NotNull、@NotEmpty、@Max、@Min、@Email、@Regex、@Future 等等……
除了我有来自 API 的 bean,我必须使用但不能修改。这意味着我无法在这些 DTO 中注释字段和方法。
如果我可以创建 mixin-like 类或接口,该类或接口与我必须在 API 中使用的真实 DTO 的结构相同,我很乐意在其上放置 bean-validation 的注释。
例如,如果我有以下无法修改的 DTO:
public class Person {
private String name;
private String dateOfBirth;
private Address address;
// constructors, getters and setters ommited
}
public class Address {
private String street;
private String number;
private String zipCode;
// constructors, getters and setters ommited
}
我将创建以下 2 个接口来模仿它们的结构并根据需要对它们进行注释:
public interface PersonMixin {
@NotBlank String name();
@Past String dateOfBirth();
@Valid @NotNull Address address();
}
public interface AddressMixin {
@NotBlank String street();
@Positive int number();
@NotBlank String zipCode(); // Or maybe a custom validator
}
如您所见,接口中的方法名称与 bean 类的属性名称相匹配。这只是一种可能的约定...
然后,理想情况下,在加载应用程序的某个地方(通常是一些 @Configuration bean)我会很乐意按照以下方式做一些事情:
ValidationMixinsSetup.addMixinFor(Person.class, PersonMixin.class);
ValidationMixinsSetup.addMixinFor(Address.class, AddressMixin.class);
除了ValidationMixinsSetup.addMixinFor 是纯粹的幻想,即它不存在。
我知道there exists a similar construct for Jackson 关于 JSON 序列化/反序列化。我多次发现它非常有用。
现在,我一直在查看 Spring 和 Hibernate Validator 的源代码。但这不是小菜一碟……我已经研究了ValidatorFactory、LocalValidatorFactoryBean、TraversableResolver 的实现,但我什至无法开始概念验证。任何人都可以对此有所了解吗? IE。不是如何实现整个功能,而是如何以及从哪里开始。我正在寻找一些关于哪些是要扩展和/或实现的基本类或接口、要覆盖哪些方法等的提示。
编辑 1: 也许这种方法不是最好的。如果您认为有更好的方法,请告诉我。
编辑 2: 至于这种方法过于复杂、过于复杂、Rube Goldberg 等,我欣赏并尊重这些观点,但我不询问通过 mixins 进行验证是好是坏,方便还是不方便,也不知道为什么会这样。通过 mixins 进行验证本身就有优点,我认为这对于一些有效的用例来说可能是一个很好的方法,即使用声明式验证而不是脚本或编程验证,同时还将验证与模型分开,让底层框架完成实际的验证工作而我只指定约束等。
【问题讨论】:
-
当您可以编写一些基本的验证代码或将您无法控制的 DTO 复制到您可以控制的类实例时,这似乎很像 Rube Goldberg。
-
@RobertHarvey 感谢您的评论。至于复制 DTO,我可以这样做,但我的新 DTO 很快就会过时。我可以处理缺少的验证,但不能处理缺少的字段。手动验证是我现在所拥有的 :) 我希望有更好的选择。
-
所以也许反思会有所帮助?如果 DTO 可以更改,则很难向其中“添加”任何代码或依赖其结构。必须指定某些东西不会改变,否则很难做好任何事情。反射可用于读取任意类并应用验证器,可能通过某种外部配置。虽然这对我来说也有点像鲁布·戈德堡。
-
@markspace 哦,对不起,我以为问题很清楚,但似乎只有我头脑清楚:需要一些约定,即带注释的接口方法必须具有相同的名称作为 bean 属性。
-
请查看文档中的这一部分 - docs.jboss.org/hibernate/stable/validator/reference/en-US/…,如果还有其他问题 - 我很乐意提供帮助
标签: java spring spring-boot bean-validation hibernate-validator