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

查看:140
本文介绍了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()将为true。

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

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

方法3:
为什么不使用这两种方法的组合?使用注释验证简单的东西,比如name属性(它很快,简洁,更易读)。保持验证器的重要验证(如果编写自定义复杂验证注释需要数小时,或者只是在无法使用注释时)。我是在一个以前的项目中做到这一点,它像一个魅力,快速和&很容易。

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
  • Latest Spring documentation about validation

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

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