【问题标题】:JSR 303 throw exception on any constraint violationJSR 303 在任何违反约束时抛出异常
【发布时间】:2017-12-20 14:33:49
【问题描述】:

我正在使用Hibernate Validator API 来验证对象上的字段。它的外观示例如下。

@NotNull @Size(min = 3, max = 8) String name;
@NotNull @Size(min = 3, max = 16) String surname;
@Size(min = 3, max = 10) String company;
// ...

现在的问题是我能够构造我的对象并且没有抛出异常。例如。

Person p = new Person("a", "b", "c");

这不会引发任何运行时异常,而是创建一个违反约束的对象。为了获得违反的约束,应从客户端代码显式调用Validator 实例。我不完全确定他们为什么这样做,但是如果对象的字段被违反,我需要构造一个对象以失败并出现一些异常。那样的话:

Person p = new Person("a", "b", "c");

... 会抛出异常。并且无法创建无效对象。这是我想要的行为。

有可能实现吗?

【问题讨论】:

    标签: java validation hibernate-validator


    【解决方案1】:

    为什么在创建对象时不检查 ctor 中的值?

    public Person(String name, String surname, String company) {
        if(name == null || name.length() < 3) {
            throw new IllegalArgumentException("useful message")
        }
    }
    

    但是,我认为这些注释仅在将对象保存到 DB 时才有效。

    【讨论】:

    • 你明白这只是一个基本的例子,试图解释我的要求吗?真实对象有 30 个字段,使用构建器模式等,所以像你建议的那样是不可能的。就像我说的,如果违反了约束,我需要构造失败
    【解决方案2】:

    Hibernate Validator 无法神奇地拦截您的构造函数来执行验证。

    所以你需要做点什么。

    您可能可以通过检测类(使用 ByteBuddy 或类似的东西)来实现您想要的,但我不确定我是否会推荐。

    最简单的方法是您创建一个服务或类似的东西来实例化您的对象,然后对其执行验证。

    【讨论】:

    • 实例化对象并在服务中验证它(或类似的东西)的问题是我的对象是使用构建器创建的。那么唯一的方法是在看起来不正确的构建方法中进行验证?当您使用我所使用的 AutoValue.Builder 时,实现起来也很棘手(但可能是可能的)
    • 您可以尝试使用 ByteBuddy 检测您的课程。不过不确定会不会更容易。
    猜你喜欢
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 2019-02-04
    • 2014-10-08
    • 2012-08-20
    相关资源
    最近更新 更多