如何让Spring-Data-MongoDB验证我的对象?

26

我有一个非常简单的Spring Boot应用程序,使用了Spring-Data-Mongodb。

我想做的就是设置一个JSR-303验证规则,指示我正在保存的对象必须具有用户名。我读到JSR-303已经在版本1.1中添加到spring-data-mongodb中,所以我假设当我保存一个对象时它会被验证,但事实并非如此。

是否有任何一个简单的示例可以展示这个工作原理?

我的用户POJO看起来像:

public class User {

    @Id
    private String id;

    @NotNull(message = "User Name is compulsory")
    private String userName;
    private String password;

    public User() {}

    public String getId() {
      return id;
    }
    public void setId(String id) {
      this.id = id;
    }

    public String getUserName() {
      return userName;
    }
    public void setUserName(String userName) {
      this.userName = userName;
    }


    public String getPassword() {
      return password;
    }
    public void setPassword(String password) {
      this.password = PasswordAuthService.hash(password);
    }
}

我在某个地方看到,只有在上下文中创建了验证器才会触发验证,因此我尝试更新我的Application类(其中包含所有配置)以使其看起来像

如果您在上下文中创建了验证器,则仅启用验证,因此我尝试更新我的Application类(它包含所有配置):

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

    @Bean
    public Validator getValidator() {
      LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
      return validator;
    }

    public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
    }

}
4个回答

41

首先确保您的类路径上有JSR-303验证器,例如:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>4.2.0.Final</version>
</dependency>
如果您使用Java配置,正确的方法是创建2个bean:
@Bean
public ValidatingMongoEventListener validatingMongoEventListener() {
    return new ValidatingMongoEventListener(validator());
}

@Bean
public LocalValidatorFactoryBean validator() {
    return new LocalValidatorFactoryBean();
}

看,验证现在已经起作用了。


1
@ZacTolley,你没有提供文章的链接吗? - Stefan van den Akker

5

从Spring Boot 2.3开始,需要在Maven的pom.xml中添加spring-boot-starter-validation依赖:

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-validation</artifactId> 
</dependency>

声明验证器Bean不是必需的。


6
我有这个依赖项,但Mongo的验证不起作用。 - LeshaRB

1

向上下文中添加Validator是一个很好的第一步,但我认为除非你要求它与其他组件交互,否则它不会与任何东西产生互动。Spring Data的开发人员可能可以确定,但我认为您还需要显式声明一些监听器。有一个旧博客文章介绍了该功能,但您和我一样可以通过谷歌搜索找到。

如果您认为在Spring Boot中有一个有用的自动配置功能,请随意在github上提出详细建议。


我看到了那篇博客文章,但我也看到那个写那篇文章的人被Spring团队要求将他所做的工作合并回核心的Spring-Data-Mongodb项目中。 - Zac Tolley
我明白了。但是你还需要添加一个类型为 ValidatingMongoEventListener 的 bean 吗? - Dave Syer
1
我就是那个人。实际上,这个变更已经在1.1.0版本中集成了,并且在当时,使用Spring Data MongoDB的xml配置,验证功能可以直接使用。@DaveSyer - 我认为这应该是Spring Data MongoDB项目的一个特性,而不是Spring Boot - 就像EnableMongoRepositories和EnableMongoAuditing一样实现。 - Maciej Walkowiak
听起来差不多就是这样。也许我们可以在 github 上讨论一下? - Dave Syer

1
我发现如果我添加

public User addUser(@RequestBody  @Valid User newUser, 
                   BindingResult bindingResult) throws Exception {

  if (bindingResult.hasErrors()) {
    throw new Exception("Validation Error");
  }

对于我的控制器而言,这将根据我的规则验证传入的JSON数据,但我仍然应该尝试设置validatingMongoEventListener来拦截任何尝试使用无效数据更新模型的代码部分。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接