java - 通过“mixins”进行验证
问题描述
我正在 Spring Boot 2+ 中开发一个 RESTful API,为此我需要执行多个验证。没什么特别的,只是典型@NotNull
的,,,,,,,,,等等……@NotEmpty
@Max
@Min
@Email
@Regex
@Future
除了我有来自 API 的 bean,我必须使用但不能修改. 这意味着我无法注释这些 DTO 中的字段和方法。
如果我可以创建与我必须在 API 中使用的真实 DTO 相同结构的mixin类或接口,那将是很棒的,我很乐意在其上放置 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
是纯粹的幻想,即它不存在。
我知道杰克逊在 JSON 序列化/反序列化方面存在类似的结构。我多次发现它非常有用。
现在,我一直在查看 Spring 和 Hibernate Validator 的源代码。但这不是小菜一碟……我已经研究了ValidatorFactory
, LocalValidatorFactoryBean
,TraversableResolver
实现,但我什至无法开始概念验证。任何人都可以对此有所了解吗?即不是如何实现整个功能,而是如何以及从哪里开始。我正在寻找一些关于哪些是要扩展和/或实现的基本类或接口、要覆盖哪些方法等的提示。
编辑1:也许这种方法不是最好的。如果您认为有更好的方法,请告诉我。
编辑2:至于这种方法过于复杂,过于复杂,Rube Goldberg等,我欣赏并尊重这些观点,但我不是在问通过 mixins 进行验证是好是坏,方便还是不方便,也不是为什么它可能是这样。通过 mixins 进行验证有其优点,我认为这对于一些有效的用例来说可能是一个很好的方法,即使用声明式验证而不是脚本式或编程式验证,同时还将验证与模型分离,让底层框架完成实际的验证工作而我只指定约束等。
解决方案
在 Person 的情况下使用编程 API(如评论中所述),您可以为您的约束应用下一个映射:
HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();
ConstraintMapping mapping = config.createConstraintMapping();
mapping.type( Person.class )
.field( "name" )
.constraint( new NotNullDef() )
.field( "number" )
.constraint( new PositiveDef() )
.field( "address" )
.constraint( new NotNullDef() )
.valid();
Validator validator = config.addMapping( mapping )
.buildValidatorFactory()
.getValidator();
当您使用 Spring 时 - 您需要在您定义验证器 bean 的一个 sping 配置文件中执行此操作。
推荐阅读
- c# - 调用框架内的表单方法
- python - 如何更改 Jupyter Notebook 中的语法高亮显示?
- java - 底部导航视图中选定选项卡的颜色保持不变
- c# - 在 Devexpress 中获取网格列值
- entity-framework-core - 使用 Fluent API entity Framework Core 2 配置多对多
- javascript - 获取 HTML、CSS 和 Javascript 文件资源的新副本
- c# - 使用 Encoding.ASCII.GetString 时获取未知字符
- java - 在我们所有商店中按产品类别查找销售明细
- android - 奇怪的布局错误
- llvm-ir - Crystal-lang:如果由 Crystal 或 clang 生成,为什么 LLVM “hello.bc”不一样?