如何使用JSR 303(Bean验证)?

5

我阅读了许多关于JSR 303规范的教程,但我没有看到任何准备好用于生产的示例。每个地方都描述了如何获取Set<Constraintviolation<T>>对象。

例如:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
Set<ConstraintViolation<Car>> violations = validator.validate(car);
但是接下来应该怎么办? 我想要通知方法调用者(客户端)该方法参数所处的状态不一致。

我该如何处理Set<ConstraintViolation<Car>>?我需要手动遍历Set<ConstraintViolation>,将所有错误信息收集到一个字符串中,然后抛出带有这些错误信息的异常吗?

还是存在一些更方便的开箱即用的方法吗?

或者在每个bean内提供validate方法会更好吗?

2个回答

2
我会选择您的第一个建议-遍历约束违规。您不一定需要创建包含所有内容的错误消息。最好只有一个错误消息,说bean <bean>无效并将约束违规设置为异常属性。
也许您需要将约束违规转换为另一个对象,否则您的应用程序将大量依赖于bean验证API。这可能是耦合过强。
您的问题在于,处理约束违规非常具体化。有很多情况下,您不想通知调用者约束违规,而是通知其他对象。例如,在Web表单中,您希望通知视图模型也显示这些约束违规。抛出异常只是另一件事。请注意,这在大多数情况下不会是ConstraintViolationException,而是特定于应用程序的异常。

请注意,在大多数情况下,这不会是ConstraintViolationException,而是应用程序特定的异常。好的,但这个特定于应用程序的异常很可能是一个特殊的异常,比如BeanValidationException,而不是像ServiceException那样适用于整个应用程序的异常?也就是说,最好创建另一个自定义异常(比如BeanValidationException)而不是重复使用现有的应用程序特定异常。谢谢。 - WelcomeTo
@MyTitle 是的,我认为最好创建一个独立于Bean验证API的异常。 - SpaceTrucker
好的,谢谢。但是你认为从服务层抛出这样的异常怎么样?允许我的EJB方法具有像throws BeanValidationException这样的签名是好还是坏?或者将其包装成服务层特定的异常会更好(但如果我包装它们,那么我就无法实现你提到的“将约束违规设置为异常属性”这个功能,因为我的服务层异常没有这样的属性)? - WelcomeTo
@我的标题,这是一场讨论。试着寻找答案。如果你找不到,可以提出更具体的问题。也许这个问题能帮到你:https://dev59.com/p2Uq5IYBdhLWcg3wKtbs - SpaceTrucker
@MyTitle 刚刚看到你是那个提问者。所以你应该坚持那里的被接受答案。 - SpaceTrucker

1
这也取决于您如何使用Bean Validation。您描述的用例是当您直接使用Bean Validation API时。在这种情况下,您将得到一个Set>作为验证调用的结果。如何处理它由您决定。然而,许多技术都集成了Bean Validation,并经常隐藏所有对Bean Validation API的直接调用。例如JPA。如果您使用JPA并且Bean Validation在类路径中,实体将在生命周期事件(预持久化/更新/删除)上自动进行验证,并且在验证错误的情况下会抛出javax.validation.ConstraintViolationException。在JSF中也是类似的,使用Bean Validation对表单元素进行验证会自动发生,并且错误也可以被突出显示。因此,除非您想使用纯Bean Validation API,否则您需要寻找有关所选技术如何与JSR 303集成的示例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接