使用hibernate validator进行数据的保存和更新信息验证

    关于hibernate validator,距4.0发布到现在已经快2年了,它是属于jsr 303的一部分,即Bean Validator。在开发过程中,经常会对输入的数据进行验证,不同的框架有不同的验证方式,可以在每个需要验证的地方进行验证,也可以使用统一的验证方式进行工作。显然使用统一的方式进行验证很有吸引力,特别是对于在进行数据的save和update时,经常会使用相同的验证逻辑以及各种重复的代码进行验证,如果能进行统一化调用,则能够减少一大段的使用代码,提高开发效率。

    首先,我们来看一个原来的验证方式,如下面的代码,这们需要对user对象的username和password进行验证,如下所示:

Asserts.assertTrue(StringUtils.hasText(getUsername()), Message.createMessage("user.username.empty"));
Asserts.assertTrue(StringUtils.hasText(getPassword()), Message.createMessage("user.password.empty"));

    上面的代码,也已经是很简练的代码了,然而也需要写两行,加上其它的验证。光数据验证就得有一大段代码。然而,不幸的是,这段代码将在进行user对象的更新时,又写一次。因为,不能保证在进行更新时会使用和添加相同的逻辑,但总有大部分是相同的,这就不能避免同样的代码编写两次。
    好了,当使用统一化的验证之后,代码变成如下形式:

validateBeanAdd();//这是对象添加验证
validateBeanUpdate(other);//这是对象更新验证

    大部分(不是全部,因为与业务相关逻辑不能统一化)的验证逻辑都使用统一验证来代替了。所有的魔法都在于如何使用hibernate validator(以下使用jsr303代替)以及相应的分组验证,并将其整合到代码中。

    首先,我们来确认验证时需要的元素信息

  1.     验证哪些信息(字段)
  2.     验证失败时的错误信息
  3.     什么时候需要验证

    幸运地是,在jsr303中,以上的3个信息均有相应的对象。其中错误信息可以通过message来指定,而不同的验证条件则可以通过group分组进行划分。那么,统一验证的逻辑可以由如下描述:

  1.     对象保存时进行以保存为分组的验证条件进行验证
  2.     对象更新时进行以更新为分组的验证条件进行验证

    那么,由上所示,修改后的user对象,可以这样来编写:

        @Column(unique = true, updatable = false, nullable = false)
        @NotNull(message="用户名不能为空", groups={Groups.Add.class,Groups.Update.class}
	public String getUsername() {
		return username;
	}

	@Column(name = "f_password")
        @NotNull(message="密码不能为空", groups={Groups.Add.class,Groups.Update.class}
	public String getPassword() {
		return password;
	}

    在添加时,统一的验证即validateBeanAdd,即可以这样来编写:

protected final void validateBeanAdd() {
		//使用validator进行判断
		List<String> strList = ValidateUtils.validateBean(this, Groups.Add.class);
		Asserts.assertTrue(strList.isEmpty(), Joins.join(strList, null));
	}

    当然,用了以上方法之后,每次验证调用一次validateBeanAdd也是不允许的,那么,我们可以写一个公共的保存方法,在此方法中调用validateBeanAdd,子类只需要重新其中可扩展的部分即可。

转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201109070002.html

相关文章:

作者: flym

I am flym,the master of the site:)

发表评论

邮箱地址不会被公开。 必填项已用*标注