基于动作的验证最佳实践 Spring MVC

Posted

技术标签:

【中文标题】基于动作的验证最佳实践 Spring MVC【英文标题】:Best practices for validation depending on actions Spring MVC 【发布时间】:2013-10-06 01:06:58 【问题描述】:

我正在尝试使用 Spring 验证来执行验证。我想知道执行主要取决于用户操作的验证的最佳做法是什么,此后,我有三种不同的方法,但我不知道哪种方法最好。

假设,我们有以下类 Foo 来验证,并且根据用户执行的操作有许多不同的验证规则。

public class Foo 
    private String name;

    private int age;

    private String description;

    private int evaluation;

    // getters, setters

执行这些验证的最佳方式是什么(例如:在创建过程中只需要姓名和年龄,在评估操作期间,我只需要验证评估等等)

解决方案 1:每个验证规则一个验证器类

public class CreateFooValidator implements Validator 
    //validation for action create

public class EvaluateFooValidator implements Validator 
    //validation for evaluate action

解决方案 2:一个具有多种方法的验证器类

public class FooValidator implements Validator 
    @Override
    public boolean supports(Class<?> clazz) 
        return Foo.class.equals(clazz);
    

    //the default validate method will be used to validate during create action

    @Override
    public void validate(Object target, Errors errors) 
    //validation required
    

    //method to validate evaluate action
    public void validateFooEvaluation(Object target, Errors errors) 
    //validation required
    
    //other validation methods for other actions

解决方案 3:Foo 类中的附加属性操作,一个验证器

public class Foo 

    private String name;

    private int age;

    private String description;

    private int evaluation;

    private String actionOnFoo;

    // getters, setters


public class FooValidator implements Validator 

    private final Foo foo = (Foo) target;
    @Override
    public boolean supports(Class<?> clazz) 
        return Foo.class.equals(clazz);
    

    @Override
    public void validate(Object target, Errors errors) 
        //test which action is performed by user
        if ("create".equals(foo.getActionOnFoo())) 
            //call for private method that performs validation for create action
        
    
    //all private methods

这 3 个或其他解决方案中最好的解决方案是什么? 谢谢!

【问题讨论】:

【参考方案1】:

使用 JSR-303 验证组,自 Spring MVC 3.1 起,@Validated 也支持。

因此,对于每个操作,您的控制器中都应该有一个方法。 为具有不同规则集的每个可能操作创建一个验证组,例如

public interface Create 


public interface Evaluate 

使用包含组的验证注释注释Foo,例如

public class Foo 

    @NotNull(groups =  Create.class, Evaluate.class )
    private String name;

    ...

    @Min(value = 1, message = "Evaluation value needs to be at least 1", groups =  Evaluate.class )
    private int evaluation;

    ...

然后使用适当的 @Validated 注释来注释控制器方法的 foo 参数,例如@Validated(Evaluate.class) 用于 evaluate 控制器方法。

您可以在此处找到另一个示例(参见第 2 项): http://blog.goyello.com/2011/12/16/enhancements-spring-mvc31/

更新: 或者,如果由于某种原因您不能/不想使用@Validated,您可以使用注入的Validator 实例并将组传递给它的validate 方法。这就是 Spring 3.1 之前的方式(就像您评论中的文章中的情况一样)。

【讨论】:

感谢您的回答。我之前已经使用过 JSR-303 验证,但不知道验证组,我将尝试一下。与此同时,我遇到了这个article。 如图所示,您当然也可以将组传递给注入的Validator。但是这篇文章是 Spring 3.1 之前的我会在答案中添加这个。【参考方案2】:

取决于你想这样做。如果您在所有验证器中应用相同的所有解决方案并且您想要验证某些业务逻辑,而不仅仅是它是否为空(为此,您可以在您的对象中使用 @Valid 注释和 @Not null 注释) .

对我来说,如果我有一个对象 Foo,我只想要一个 Validator 用于这个对象,然后我有几种方法来验证数据取决于我在控制器中的需要,例如,一种用于保存新的 Foo 或另一种用于在更新之前进行验证等...

【讨论】:

以上是关于基于动作的验证最佳实践 Spring MVC的主要内容,如果未能解决你的问题,请参考以下文章

JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践

JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践

Spring MVC学习笔记——JSR303介绍及最佳实践

ehcache 或 Spring MVC 的 Spring 缓存中的最佳缓存实践是啥?

保护spring mvc和hibernate的最佳实践

Spring MVC 领域对象处理最佳实践