Spring MVC:如何执行验证? [英] Spring MVC: How to perform validation?

查看:24
本文介绍了Spring MVC:如何执行验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道什么是对用户输入执行表单验证的最干净和最好的方法.我见过一些开发者实现了 org.springframework.validation.Validator.关于这个问题:我看到它验证了一个类.是否必须使用来自用户输入的值手动填充类,然后传递给验证器?

I would like to know what is the cleanest and best way to perform form validation of user inputs. I have seen some developers implement org.springframework.validation.Validator. A question about that: I saw it validates a class. Does the class have to be filled manually with the values from the user input, and then passed to the validator?

我对验证用户输入的最干净和最好的方法感到困惑.我知道使用 request.getParameter() 然后手动检查 nulls 的传统方法,但我不想在我的 中进行所有验证控制器.在这方面的一些好的建议将不胜感激.我没有在这个应用程序中使用 Hibernate.

I am confused about the cleanest and best way to validate the user input. I know about the traditional method of using request.getParameter() and then manually checking for nulls, but I don't want to do all the validation in my Controller. Some good advice on this area will be greatly appreciated. I am not using Hibernate in this application.

推荐答案

使用 Spring MVC,有 3 种不同的方式来执行验证:使用注解、手动或两者的混合.没有一种独特的最干净和最好的方法"来验证,但可能有一种更适合您的项目/问题/上下文.

With Spring MVC, there are 3 different ways to perform validation : using annotation, manually, or a mix of both. There is not a unique "cleanest and best way" to validate, but there is probably one that fits your project/problem/context better.

让我们有一个用户:

public class User {

    private String name;

    ...

}

方法 1 :如果您有 Spring 3.x+ 和简单的验证要做,请使用 javax.validation.constraints 注释(也称为 JSR-303 注释).

Method 1 : If you have Spring 3.x+ and simple validation to do, use javax.validation.constraints annotations (also known as JSR-303 annotations).

public class User {

    @NotNull
    private String name;

    ...

}

您的库中将需要一个 JSR-303 提供程序,例如 Hibernate Validator是参考实现(这个库与数据库和关系映射无关,它只是做验证:-).

You will need a JSR-303 provider in your libraries, like Hibernate Validator who is the reference implementation (this library has nothing to do with databases and relational mapping, it just does validation :-).

然后在你的控制器中你会有类似的东西:

Then in your controller you would have something like :

@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() 将为真.

Notice the @Valid : if the user happens to have a null name, result.hasErrors() will be true.

方法 2 :如果您有复杂的验证(如大型企业验证逻辑、跨多个字段的条件验证等),或者由于某种原因无法使用方法 1,请使用手动验证.将控制器的代码与验证逻辑分开是一个很好的做法.不要从头开始创建验证类,Spring 提供了一个方便的 org.springframework.validation.Validator 接口(自 Spring 2 起).

Method 2 : If you have complex validation (like big business validation logic, conditional validation across multiple fields, etc.), or for some reason you cannot use method 1, use manual validation. It is a good practice to separate the controller’s code from the validation logic. Don't create your validation class(es) from scratch, Spring provides a handy org.springframework.validation.Validator interface (since Spring 2).

所以假设你有

public class User {

    private String name;

    private Integer birthYear;
    private User responsibleUser;
    ...

}

并且您想要进行一些复杂"的验证,例如:如果用户的年龄未满 18 岁,则负责用户不得为空且负责用户的年龄必须超过 21.

and you want to do some "complex" validation like : if the user's age is under 18, responsibleUser must not be null and responsibleUser's age must be over 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

    }

}

然后在您的控制器中,您将拥有:

Then in your controller you would have :

@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() 将为真.

If there are validation errors, result.hasErrors() will be true.

注意:您还可以在控制器的@InitBinder 方法中设置验证器,使用binder.setValidator(...)"(在这种情况下,方法 1 和 2 的混合使用是不可能的,因为您替换默认验证器).或者您可以在控制器的默认构造函数中实例化它.或者在控制器中注入一个 @Component/@Service UserValidator(@Autowired):非常有用,因为大多数验证器都是单例 + 单元测试模拟变得更容易 + 你的验证器可以调用其他 Spring 组件.

Note : You can also set the validator in a @InitBinder method of the controller, with "binder.setValidator(...)" (in which case a mix use of method 1 and 2 would not be possible, because you replace the default validator). Or you could instantiate it in the default constructor of the controller. Or have a @Component/@Service UserValidator that you inject (@Autowired) in your controller : very useful, because most validators are singletons + unit test mocking becomes easier + your validator could call other Spring components.

方法三:为什么不结合使用这两种方法呢?使用注释验证简单的东西,例如名称"属性(这样做很快,简洁且更具可读性).保留对验证器的大量验证(当编写自定义复杂验证注释需要数小时,或者仅当无法使用注释时).我在以前的一个项目上做过这个,它的效果非常好,快速&很简单.

Method 3 : Why not using a combination of both methods? Validate the simple stuff, like the "name" attribute, with annotations (it is quick to do, concise and more readable). Keep the heavy validations for validators (when it would take hours to code custom complex validation annotations, or just when it is not possible to use annotations). I did this on a former project, it worked like a charm, quick & easy.

警告:您不能将验证处理误认为异常处理.阅读这篇文章以了解何时使用它们.

Warning : you must not mistake validation handling for exception handling. Read this post to know when to use them.

参考资料:

  • A very interesting blog post about bean validation (Original link is dead)
  • Another good blog post about validation (Original link is dead)
  • Latest Spring documentation about validation

这篇关于Spring MVC:如何执行验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆