使用 Spring MVC,有 3 种不同的方式来执行验证:使用注解、手动或两者混合。没有一种独特的“最干净和最好的方法”来验证,但可能有一种更适合您的项目/问题/上下文。
让我们有一个用户:
public class User {
private String name;
...
}
方法 1:如果您有 Spring 3.x+ 和简单的验证,请使用javax.validation.constraints
注解(也称为 JSR-303 注解)。
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() 将为真。
方法2:如果你有复杂的验证(比如大业务验证逻辑,跨多个字段的条件验证等),或者由于某种原因你不能使用方法1,使用手动验证。将控制器的代码与验证逻辑分开是一种很好的做法。不要从头开始创建验证类,Spring 提供了一个方便的org.springframework.validation.Validator
接口(从 Spring 2 开始)。
所以假设你有
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() 将为真。
注意:您还可以使用“binder.setValidator(...)”在控制器的 @InitBinder 方法中设置验证器(在这种情况下,方法 1 和 2 的混合使用是不可能的,因为您替换了默认值验证器)。或者您可以在控制器的默认构造函数中实例化它。或者在控制器中注入一个@Component/@Service UserValidator(@Autowired):非常有用,因为大多数验证器都是单例 + 单元测试模拟变得更容易 + 你的验证器可以调用其他 Spring 组件。
方法3:
为什么不结合使用这两种方法?使用注释验证简单的东西,例如“名称”属性(它做起来很快,简洁且更具可读性)。为验证器保留繁重的验证(当编写自定义复杂验证注释需要数小时,或者只是在无法使用注释时)。我在以前的项目中这样做过,它就像一个魅力,又快又容易。
警告:您不能将验证处理误认为是异常处理。阅读这篇文章以了解何时使用它们。
参考 :