使用Spring MVC,有3种不同的方法来执行验证:使用注释,手动或两者混合使用。没有一种独特的“最干净和最好的方法来验证”,但可能有一种更适合你的项目/问题/上下文。
让我们有一个用户:
public class User {
private String name;
...
}
方法 1 :如果您有Spring 3.x+和简单的验证要做,请使用注释(也称为JSR-303注释)。javax.validation.constraints
public class User {
@NotNull
private String name;
...
}
你的库中需要一个 JSR-303 提供程序,比如 Hibernate Validator,它是参考实现(这个库与数据库和关系映射无关,它只是执行验证 :-)。
然后在你的控制器中,你会有这样的东西:
@RequestMapping(value="/user", method=RequestMethod.POST)
public createUser(Model model, @Valid @ModelAttribute("user") User user, BindingResult result){
if (result.hasErrors()){
// do something
}
else {
// do something else
}
}
请注意@Valid:如果用户碰巧有一个空名称,则 result.hasErrors() 将为 true。
方法 2 :如果您有复杂的验证(如大型业务验证逻辑、跨多个字段的条件验证等),或者由于某种原因您无法使用方法 1,请使用手动验证。最好将控制器的代码与验证逻辑分开。不要从头开始创建验证类,Spring提供了一个方便的界面(从Spring 2开始)。org.springframework.validation.Validator
所以假设你有
public class User {
private String name;
private Integer birthYear;
private User responsibleUser;
...
}
并且您希望执行一些“复杂”验证,例如:如果用户的年龄小于18岁,则责任用户不得为空,责任用户的年龄必须超过21岁。
你会做这样的事情
public class UserValidator implements Validator {
@Override
public boolean supports(Class clazz) {
return User.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
if(user.getName() == null) {
errors.rejectValue("name", "your_error_code");
}
// do "complex" validation here
}
}
然后在您的控制器中,您将拥有:
@RequestMapping(value="/user", method=RequestMethod.POST)
public createUser(Model model, @ModelAttribute("user") User user, BindingResult result){
UserValidator userValidator = new UserValidator();
userValidator.validate(user, result);
if (result.hasErrors()){
// do something
}
else {
// do something else
}
}
如果存在验证错误,则 result.hasErrors() 将为 true。
注意:您也可以在控制器的@InitBinder方法中设置验证器,使用“binder.setValidator(...)”(在这种情况下,混合使用方法 1 和 2 是不可能的,因为您替换了默认验证程序)。或者,您可以在控制器的默认构造函数中实例化它。或者有一个@Component/@Service UserValidator,你注入(@Autowired)到你的控制器中:非常有用,因为大多数验证器都是单例+单元测试模拟变得更容易+你的验证器可以调用其他Spring组件。
方法 3 :为什么不结合使用这两种方法呢?使用注释验证简单的东西,如“name”属性(它快速完成,简洁且更具可读性)。保留对验证者的繁重验证(当编写自定义复杂验证批注需要数小时时,或者只是在无法使用批注时)。我在以前的一个项目上做了这个,它就像一个魅力,快速而简单。
警告:不得将验证处理误认为是异常处理。阅读这篇文章,了解何时使用它们。
引用: