Spring MVC使用hibernate Validator来验证单个基本类型

时间:2014-07-15 20:03:41

标签: java spring-mvc hibernate-validator

下面是我遇到问题的映射方法,无论我传递给它什么值,验证都会返回"通过验证。"

@RequestMapping(value = "test", method = RequestMethod.POST)
@ResponseBody
public String getTest(@RequestBody @Valid @Max(32) long longValue, BindingResult result) {
  if (result.hasErrors()) {
    return "failed validation";
  } else {
    return "passed validation";
  }
}

我知道@Max适用于我的应用程序,因为我使用它来验证将大量数据返回给控制器的自定义对象。在这种情况下我只调用@Valid和方法参数中对象的验证类型,它不会运行验证。

hibernate-validator不允许这样做吗?

我希望不必定义一个只包含long值的对象,以便我可以对其进行验证。

3 个答案:

答案 0 :(得分:3)

  

我希望不必定义只包含long的对象   值只是为了让我可以对它进行验证。

定义包装bean将是最聪明的举措,因为hibernate-validator完全以bean的概念为中心,并且毕竟是bean验证规范的参考实现。该规范的主要推动者之一是承认验证是跨越不同应用层的跨领域关注点,并提供一种优雅地处理此问题的机制。这就是为什么它以bean为中心,它是通过层的对象。

另一方面,在程序上验证原始程序毕竟不是什么大问题,你的代码可以简单地类似

@RequestMapping(value = "test", method = RequestMethod.POST)
@ResponseBody
public String getTest(@RequestBody long longValue, BindingResult result) {
  if (longValue > 32) {
     result.rejectValue("longValue", "error.longValue", "longValue max constrained failed");
    return "failed validation";
  } else {
    return "passed validation";
  }
}

所以在我看来,如果它足够简单,要么进行程序验证,要么只是包装值。

答案 1 :(得分:2)

不,不允许。我明白你的观点但JSR-303规范(hibernate验证器实现)是用于bean验证的,请参阅here

答案 2 :(得分:2)

首先,正如其他答案所述,Hibernate Validator不允许直接验证原语,如问题中的示例。为了使用Hibernate Validator,定义一个包含long值的新类正是使用Hibernate Validator所需要的。

其次,最重要的是,程序验证是有效的,而且很简单,它不干净且可维护。让我用一些例子来说明这一点:

@RequestMapping(value = "testA", method = RequestMethod.POST)
@ResponseBody
public String getTestA(@RequestBody long longValue, BindingResult result) {
   if (longValue > 32) {
     result.rejectValue("longValue", "error.longValue", "longValue max constrained failed");
     return "failed validation for test A";
   } else {
     return "passed validation for test A";
   }
}


@RequestMapping(value = "testB", method = RequestMethod.POST)
@ResponseBody
public String getTestB(@RequestBody long longValue, BindingResult result) {
   if (longValue > 32) {
     result.rejectValue("longValue", "error.longValue", "longValue max constrained failed");
     return "failed validation for test B";
   } else {
     return "passed validation for test B";
   }
}


@RequestMapping(value = "testC", method = RequestMethod.POST)
@ResponseBody
public String getTestC(@RequestBody long longValue, BindingResult result) {
   if (longValue > 32) {
     result.rejectValue("longValue", "error.longValue", "longValue max constrained failed");
     return "failed validation for test C";
   } else {
     return "passed validation for test C";
   }
}

首先要注意的是,使用3个简单函数,所有验证代码都是重复的。

其次,如果在某些时候您的验证要求发生变化,现在所有长值都必须大于35,那么您需要更改每个验证函数,并且在此示例中非常简单,因为只有3个函数同样的验证,但想象一下它是100个函数,你执行相同的验证,现在很痛苦。

因此,只需使用long值和验证注释定义一个新类,并在每个方法上使用该类,就可以删除代码重复,并且当您的验证要求发生变化时,在一个地方应用更改时,您已经保留了代码。

此外,为一个特定任务定义类没有任何错误,事实上,这正是Single Responsability Principle告诉你要做的事情。

编辑:添加了指向SRP说明的链接。