1

我正在使用带有休眠验证器 4.2 的 spring 3.1。我观察到休眠验证被调用了两次:一次在控制器级别,当我使用如下方法时:

 @RequestMapping(method = RequestMethod.POST)
    public String onSubmit(@Valid User user, BindingResult result) {....}

第二次将实体作为以下内容持久化:

org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(..)
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(..)
org.hibernate.action.EntityUpdateAction.preUpdate(..)

我相信在控制器级别进行验证并显示带有错误消息的错误页面更有意义。无论如何,在流程中进行两次相同的验证并不好。我在休眠文档中发现可以通过在休眠配置中设置为 false 来关闭它,hibernate.validator.autoregister_listeners但不建议这样做。

那么推荐的验证方法是什么?同样在我的特殊情况下,第二次验证会引起麻烦,因为我有一个字段' confirmPassword',当用户提交表单时需要进行验证,但表中不需要,所以每当我必须保存、更新用户时,我必须设置confirmPassword不必要的字段只是为了验证通过。

4

2 回答 2

1

尽管有外表,但验证并不是一件容易的事。

前端验证适用于填写表单的用户,并且可以从一个视图更改为另一个视图(例如不同的消息)。视图中必填字段的消息应该是“该字段是强制性的!”,在实体被持久化的后端:“字段不能为空”。

后端验证应始终在保存类时进行,考虑事实上可以保存持久实体而无需从视图传递(例如,从从 web 服务或队列或其他来源接收数据的批处理中......)。

如果您在实体级别放置验证注释,则您在该类上强制执行合同,该合同独立于该类已在视图中使用与否这一事实。

ConfirmPassword 是一个视图字段,所以我认为不应该作为字段出现在实体中(例如,我用 JSF 开发了一个类似的案例,我将 confirmPassword 放在与该视图相关的 ManagedBean 中而不是实体中,实体只包含密码字段)。

因此,总结一下,我认为两次“相同”验证是正确的。

于 2012-09-24T14:47:22.183 回答
0

一切都取决于用例,并在一定程度上取决于个人品味。@obe6 建议使用两个单独的 bean,它们在某些情况下可能有用,但在其他情况下则不然。关于confirmPassword字段,您始终可以在您的实体中将其标记为@Transient,这样该值就不会被持久化。

就我个人而言,我可能会通过 @Valid 禁用 Spring 验证,因为它不是标准的。另一方面是 JPA 生命周期事件的 Bean Validation。我想这是另一个口味问题。不过,两者似乎都没有必要。

于 2012-09-25T08:08:11.767 回答