如您所注意到的,现在是春季大扫除的时候,每个人都推出了其新的JSR提案,遵循EE 7。我想与您分享我对Bean Validation的想法。这绝对不是一份确定的列表,而是一个进一步讨论的起点。最终,EG和社区将塑造规范。
首先,我认为人们对Bean Validation(没有重大缺陷或限制)非常满意。因此,我们的想法是推出1.1版本,而不是2.0版本。
与其他规范的集成
虽然Bean Validation JSR不包括在内,但我认为与一些其他JSR负责人进一步合作,探讨如何将Bean Validation集成到SE/EE平台的各种生命周期中,是非常重要的。当然,没有人希望每个规范都发明自己的验证机制和自己的注解。我们与JPA 2和JSF 2的合作表明,这对平台和开发者都是可能且有益的。
- JAX-RS:在HTTP方法调用参数上调用Bean Validation。如果参数无效,JAX-RS可以返回适当的HTTP错误代码,以及一些描述错误的负载。
- JAXB:有人要求Bean Validation与JAXB集成。基本上,Bean Validation约束(至少是基本约束)可以转换为XML模式描述符(反之亦然),以确保Java领域和XML领域之间的统一传播。我与Martin Grebac探讨了其中的一些需求,希望我们能达成一致。
- JPA:通过让Bean Validation约束影响在实体模型上声明的约束生成的DDL来改进集成
- CDI:提供一种方法,允许Bean Validation可插入组件以实现CDI风格的注入(特别是约束验证器实现)
- CDI:集成方法级验证(见下文)
方法级验证
我们的想法是提供API来验证方法调用的参数和返回值。这些API将用于任何围绕方法调用的注入或AOP框架。如果检测到约束违规,将抛出一个异常(例如。ConstraintViolationException)。
public class OrderManager { public void processOrder(@Valid Order order, @Min(0) @Max(30) int retry) { doProcessOrder(...) } }
如果Order包含约束违规或如果retry的值不在0到30之间,拦截器框架将抛出。ConstraintViolationException异常。
拦截器框架可以是
- CDI:某些具有特定类型的拦截器可以在访问时触发方法验证
- AOP风格的框架,如Javassist或AspectJ
@Valid和组传播
有些人需要能够在级联验证时将一个组转换为另一个组。这可以帮助减少组数并提高复用性。
public class Address { @NotNull String city; @Valid(from=Default.class, to=EnhancedGroup.class) Country country; } public class Country { @NotNull(groups=EnhancedGroup.class) String name; @Size(min=2, max=2, groups=EnhancedGroup.class) String iso2; }
对集合元素应用约束
虽然我们可以验证集合本身的约束并要求级联验证到集合的元素上,但我们不能对集合元素本身应用约束。对于原生类型的集合来说,这尤其令人烦恼。有几个不太优雅的解决方案来解决这个问题,真正的解决方案是等待Java类型的注解(JSR-308)
Collection<@NotNull String> names;
根据JSR-308最终发布的时间,我们可能需要推迟这个功能。
各种问题
不分先后,以下是一些我们可以尝试解决的问题或特性。
约束组合
今天约束组合是通过逻辑与(所有约束都必须有效)完成的。我们也可以支持逻辑或组合。
@ConstraintComposition(OR) @SSN @TemporarySSN @Constraint(validatedBy = { }) @ReportAsSingleViolation @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) public @interface ValidSSN { String message() default "Not a valid social security number"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; }
JTA和异常传播
在EE中,在业务方法过程中抛出异常的方式存在一些不一致性
- 由声明式或显式的commit()调用引发
- 基本来说,当操作(如验证)在声明式
commit()内部触发时,我相信所有内容都被包装在一个RollbackException中。这意味着根据JPA的flush()何时被调用ConstraintViolationException(由JPA引发),它要么是无辜的,要么被包装在RollbackException中。我想知道我们能否解决这个问题的不一致性。
对OSGi风格容器的更好规则
一些极端模块化粉丝对规范中关于可见性和类加载器的一些模糊性提出了投诉。我们应该澄清这一点。
在@BigDecimal / @BigInteger上设置排他标志
允许排除限制。
ConstraintViolationException构建器
我们的想法是提供一个简单的API来构建一致的ConstraintViolationException。因为Bean Validation通常由其他规范或框架的生命周期调用,它们负责抛出异常。
您的参与
这就是我所有的。我相信我遗漏了许多改进,所以请提出意见。您可以按照您喜欢的任何方式做
- 在博客条目上评论
- 在规范问题跟踪器上打开一个问题
- 在Bean Validation论坛上讨论
当然,您总是可以领先一步。
从这第一波反馈中,我计划向JCP提出一个JSR。
请注意,Hibernate Validator 4.2已集成或将要集成一些这些功能,这将为我们提供反馈。
Emmanuel