java-来自javax.validation.constraints的注释不起作用

使用id(如name@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));

为什么这不适用idname的约束? 我还需要做什么?

11个解决方案
50 votes

为了使JSR-303 bean验证在Spring中工作,您需要做一些事情:

  1. 注释的MVC名称空间配置:@Valid
  2. JSR-303规格JAR:@Valid(看起来您已经拥有了)
  3. 规范的实现,例如休眠验证,它似乎是最常用的示例:@Valid
  4. 在要验证的bean中,来自规范JAR或来自实现JAR(您已经完成)的验证批注
  5. 在要验证的处理程序中,使用@Valid注释要验证的对象,然后在方法签名中包括BindingResult,以捕获错误。

例:

@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....
    }
}
atrain answered 2020-07-09T09:20:29Z
28 votes

您应该使用Validator来检查您的课程是否有效。

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

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

Artem answered 2020-07-09T09:20:53Z
5 votes

如果要验证实体,则必须在实体上调用验证器。 然后,您将获得一组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
}
Nikola Yovchev answered 2020-07-09T09:21:23Z
5 votes

您也可以直接将29586418800000000627712与lombok库结合使用,至少对于@NotNull场景而言。 更多详细信息:[https://projectlombok.org/api/lombok/NonNull.html]

Andreas Dietrich answered 2020-07-09T09:21:43Z
1 votes

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

@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;
}

对我来说似乎是越野车的行为,但我想它很容易解决

ChetPrickles answered 2020-07-09T09:22:12Z
1 votes

几年后我来到这里,由于上面的atrain评论,我可以解决它。 就我而言,我在API中缺少@Valid,该API接收了用@Valid注释的对象(在我的情况下为POJO)。此问题已解决。

我不需要向用@Size注释的变量中添加任何额外的注释,例如2958642699701847847或@NotBlank,仅是变量中的约束以及我在API中提到的约束...

Pojo课程:

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

API类:

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

谢谢和欢呼

xCovelus answered 2020-07-09T09:22:49Z
0 votes

您需要向每个成员变量添加@Valid,这也是一个包含验证约束的对象。

Chad answered 2020-07-09T09:23:09Z
0 votes

因此,服务接口处的@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
Akshay answered 2020-07-09T09:23:34Z
0 votes

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

Edward answered 2020-07-09T09:23:54Z
0 votes

来自atrain的好答案,但是捕获异常的更好解决方案是利用自己的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。

PavelP answered 2020-07-09T09:24:19Z
-1 votes

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

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

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

*在Udemy的“春季和初学者冬眠”课程中拍摄的快照

Junda Yang answered 2020-07-09T09:24:52Z
translate from https://stackoverflow.com:/questions/8756768/annotations-from-javax-validation-constraints-not-working