12

我正在尝试使用 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 或其他解决方案中最好的解决方案是什么?谢谢!

4

2 回答 2

19

Use JSR-303 Validation Groups, which are since Spring MVC 3.1 also supported by @Validated.

So, for each action you should have a method in your controller. Create a validation group for each possible action that has a different set of rules, e.g.

public interface Create {
}

public interface Evaluate {
}

Annotate Foo with the validation annotations including the group, e.g.

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;

    ...
}

Then annotate the foo argument of your controller methods with the appropriate @Validated annotation, e.g. @Validated({Evaluate.class}) for the evaluate controller method.

You can find another example here (see item 2): http://blog.goyello.com/2011/12/16/enhancements-spring-mvc31/

Update: Alternatively, if for some reason you can't / don't want to use @Validated, you can use an injected Validator instance and pass the groups to its validate method. That's the way it was done before Spring 3.1 (as is the case in the article in your comment).

于 2013-09-30T08:36:26.610 回答
1

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

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

于 2013-09-30T08:41:52.070 回答