来自javax.validation.constraints的注释无效

时间:2012-01-06 10:56:48

标签: java spring annotations constraints bean-validation

使用来自javax.validation.constraints的{​​{1}},@Size等注释需要哪些配置?这是我的代码:

@NotNull

当我尝试在另一个类中使用它时,验证不起作用(即创建对象时没有错误):

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Person {
      @NotNull
      private String id;

      @Size(max = 3)
      private String name;

      private int age;

      public Person(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
      }
}

为什么这不适用于Person P = new Person(null, "Richard3", 8229)); id的约束?我还需要做什么?

17 个答案:

答案 0 :(得分:48)

要使JSR-303 bean验证在Spring中运行,您需要做几件事:

  1. 注释的MVC命名空间配置:<mvc:annotation-driven />
  2. JSR-303规范JAR:validation-api-1.0.0.GA.jar(看起来你已经有了)
  3. 规范的实现,例如Hibernate Validation,它似乎是最常用的示例:hibernate-validator-4.1.0.Final.jar
  4. 在要验证的bean中,验证注释,来自规范JAR或来自实现JAR(您已经完成)
  5. 在要验证的处理程序中,使用@Valid注释要验证的对象,然后在方法签名中包含BindingResult以捕获错误。
  6. 示例:

    @RequestMapping("handler.do")
    public String myHandler(@Valid @ModelAttribute("form") SomeFormBean myForm, BindingResult result, Model model) {
        if(result.hasErrors()) {
          ...your error handling...
        } else {
          ...your non-error handling....
        }
    }
    

答案 1 :(得分:28)

您应该使用Validator来检查您的班级是否有效。

Person person = ....;
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
Set<ConstraintViolation<Person>> violations = validator.validate(person);

然后,迭代违规设置,您可以找到违规行为。

答案 2 :(得分:6)

就我而言,我使用的是Spring Boot版本2.3.0。当我将maven依赖关系更改为使用2.1.3时,它起作用了。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.3.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
    </dependency>
</dependencies>

答案 3 :(得分:5)

如果要对其进行验证,必须在实体上调用验证器。然后你会得到一组ConstraintViolationException,它基本上显示你的实体的哪个字段存在约束违规以及究竟是什么。也许您也可以共享一些您希望验证实体的代码。

如果在事务期间使用多个数据修改或在获得验证异常时执行其他操作,则常用的技术是在@PrePersist和回滚事务中进行验证。

您的代码应该是这样的:

@PrePersist
public void prePersist(SomeEntity someEntity){
    Validator validator = Validation.buildDefaultValidatorFactory.getValidator();
    Set<ConstraintViolation<SomeEntity>> = validator.validate(someEntity);
    //do stuff with them, like notify client what was the wrong field, log them, or, if empty, be happy
}

答案 4 :(得分:4)

您也可以将 @NonNull lombok库一起使用,至少用于@NotNull方案 。更多详情:https://projectlombok.org/api/lombok/NonNull.html

答案 5 :(得分:1)

在我的情况下,我有一个未被调用的自定义类级别约束。

@CustomValidation // not called
public class MyClass {
    @Lob
    @Column(nullable = false)
    private String name;
}

一旦我向我的类添加了字段级约束(自定义或标准),类级约束就开始工作了。

@CustomValidation // now it works. super.
public class MyClass {
    @Lob
    @Column(nullable = false)
    @NotBlank // adding this made @CustomValidation start working
    private String name;
}

对我来说似乎是错误的行为,但我很容易解决这个问题

答案 6 :(得分:1)

在版本2.3.0之后,“ spring-boot-strarter-test ”(包括NotNull / NotBlank / etc)现在为“ sprnig boot-strarter-validation

只需将其从 ....-测试更改为 ...- validation ,它就可以工作。

如果不将正在使用的版本降级到2.1.3,也可以解决。

答案 7 :(得分:0)

我也遇到了同样的问题。 Javax 注释(@NotNull、@Valid)未执行任何验证。他们的存在没有任何影响。

我必须使用“springboot-starter-validation”依赖项才能使 javax 验证有效。 这里是相关的依赖配置。另外不要错过在要验证的对象上添加@Valid 注解。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
.....
.....
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

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

    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
 <dependencies>

答案 8 :(得分:0)

对于那些无法通过 Hibernate 验证依赖执行服务器端验证的人。 只需删除 Hibernate 验证器 +javax 验证依赖项并添加 spring-boot-starter 验证。它在内部提供 Hibernate Validator,对我来说效果很好。

致谢:- 来自 youtube 的评论。

答案 9 :(得分:0)

如果您正在使用lombok,则可以使用@NonNull注释插入。 或只需在pom.xml文件中添加javax.validation依赖项。

答案 10 :(得分:0)

火车的好答案, 但也许捕获异常的更好解决方案是利用自己的 HandlerExceptionResolver 赶上

@Override
public ModelAndView resolveException(
    HttpServletRequest aReq, 
    HttpServletResponse aRes,
    Object aHandler, 
    Exception anExc
){
    // ....
    if(anExc instanceof MethodArgumentNotValidException) // do your handle     error here
}

然后,您可以保持处理程序尽可能整洁。 您不再需要myHandlerMethod中的BindingResult,Model和SomeFormBean。

答案 11 :(得分:0)

几年后,我来到这里,由于atraincomment above,我可以解决它。在我的情况下,我在 API 中丢失了@Valid,该API接收了用@Size注释的对象(在我的情况下为POJO)。它解决了这个问题。

我确实不需要向变量@Valid添加任何额外的注释,例如@NotBlank@Size,只是变量中的约束以及我在API中提到的内容...

Pojo课程:

...
@Size(min = MIN_LENGTH, max = MAX_LENGTH);
private String exampleVar;
...

API类:

...
public void exampleApiCall(@RequestBody @Valid PojoObject pojoObject){
  ...
}

感谢和欢呼

答案 12 :(得分:0)

对于方法参数,您可以像这样使用Objects.requireNonNull(): test(String str) { Objects.requireNonNull(str); } 但这仅在运行时检查,如果为null,则抛出NPE。这就像先决条件检查。但这可能就是您想要的。

答案 13 :(得分:0)

因此服务接口的@Valid仅适用于该对象。如果您在ServiceRequest对象的层次结构中有任何更多验证,那么您可能已明确触发验证。所以我就这样做了:

public class ServiceRequestValidator {

      private static Validator validator;

      @PostConstruct
      public void init(){
         validator = Validation.buildDefaultValidatorFactory().getValidator();
      }

      public static <T> void validate(T t){
        Set<ConstraintViolation<T>> errors = validator.validate(t);
        if(CollectionUtils.isNotEmpty(errors)){
          throw new ConstraintViolationException(errors);
        }
     }

}

如果要触发对该对象的验证,则需要在对象级别进行以下注释。

@Valid
@NotNull

答案 14 :(得分:0)

您需要将 @Valid 添加到 每个成员变量 ,这也是包含验证限制的对象。

答案 15 :(得分:-1)

我最近在非常相似的情况下遇到了这个问题: 满足了所有要求,成为列出的评分最高的答案,但仍然得到了错误的结果。

因此,我查看了我的依赖项,发现我缺少了一些依赖项。我通过添加缺少的依赖项来纠正它。

我正在使用休眠模式,所需的依赖项为: Dependencies Snapshot

* Udemy在“ Spring&Hibernate for Beginners”课程中拍摄的快照

答案 16 :(得分:-1)

就我而言,我删除了这些行

1-import javax.validation.constraints.NotNull;

2-import javax.validation.constraints.Size;

3- @NotNull

4- @Size(max = 3)