1

我们在 Spring MVC 中使用@Min、@Max、@NotNull 等注释进行服务器端验证。这些注释应该放在模型类中。假设我想在需要时应用这样的注释,我不想在模型类中应用这样的注释。

例如。

我有一个类 Person,其属性为 Name、Gender、Email。如果我将@NotNull 注释放在电子邮件属性上,那么它将在全球范围内应用,如果我的要求发生变化,例如在我的系统中有两个人 Student 和 Teacher 并且对于教师注册电子邮件是可选的,但对于 Student 它不为空,那么我怎么能做到这一点。

在上述示例的情况下,我可以动态应用验证注释吗?

如果 UserRegistration 是针对教师的,那么电子邮件是可选的。

如果 UserRegistration 是针对学生的,那么电子邮件是强制性的。

4

3 回答 3

6

为了实现这种行为,我建议使用动态激活的组。看看我下面的例子。

Person.java

class Person {

    @NotNull(groups = StudentChecks.class)
    @Email
    private email;

    // other members with getters/setters

    public interface StudentChecks {
    }
}

在这种情况下,只有在激活组@NotNull时才会执行约束。StudentChecks要按条件激活验证组,Spring 提供了特殊的注释@Validated

StudentController.java

@Controller
public class StudentController {

    @RequestMapping(value = "/students", method = RequestMethod.POST)
    public String createStudent(@Validated({Person.StudentChecks.class}) Person student, BindingResult result) {
        // your code
    }

}

您可以在此处找到更多详细信息:

于 2013-01-08T10:13:22.930 回答
1

您将需要实现自己的验证器并将其注册到您的控制器中。

于 2013-01-08T09:48:57.453 回答
0

这是使用 bean 验证提出的问题之一。事实上,它们实际上是在全球范围内应用的。

一个常见的问题是更新具有@before 或@after 注释的日期的实体导致无效更新,实际上这些不应该被检查。

解决此问题的常用方法是使用 DTO 或数据传输对象,而不是直接在控制器中接受模型对象,而是为该操作创建一个专门的类(您可以在其他操作中重用它。这样您还可以断开您的从你的软件实际做的模型,它更安全,因为spring只是绑定你扔给他的所有东西.例如,如果一个用户对象有一个管理标志,如果这个管理标志被发布并设置为true,spring会很乐意填充它在您的模型对象中。使用 DTO,您可以复制您需要的字段并忽略其余部分。

于 2013-01-08T09:58:22.753 回答