it-swarm.com.de

Anmerkungen aus javax.validation.constraints funktionieren nicht

Welche Konfiguration ist erforderlich, um Anmerkungen von javax.validation.constraints wie @Size, @NotNull usw. zu verwenden? Hier ist mein Code:

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

Wenn ich versuche, es in einer anderen Klasse zu verwenden, funktioniert die Überprüfung nicht (d. H. Das Objekt wird ohne Fehler erstellt):

Person P = new Person(null, "Richard3", 8229));

Warum gelten keine Einschränkungen für id und name? Was muss ich noch tun?

39
Darshan Patil

Damit die JSR-303-Bean-Validierung im Frühling funktioniert, benötigen Sie Folgendes:

  1. MVC-Namespace-Konfiguration für Anmerkungen: <mvc:annotation-driven />
  2. Der JSR-303 spec JAR: validation-api-1.0.0.GA.jar (sieht so aus, als hätten Sie das schon)
  3. Eine Implementierung der Spezifikation, z. B. "Hibernate Validation", die das am häufigsten verwendete Beispiel darstellt: hibernate-validator-4.1.0.Final.jar
  4. Validierungsanmerkungen in der zu validierenden Bean, entweder aus der Spezifikations-JAR oder aus der Implementierungs-JAR (was Sie bereits getan haben)
  5. Kommentieren Sie in dem Handler, den Sie validieren möchten, das Objekt, das Sie mit @Valid validieren möchten, und fügen Sie anschließend eine BindingResult in die Methodensignatur ein, um Fehler zu erfassen. 

Beispiel:

@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....
    }
}
46
atrain

Sie sollten Validator verwenden, um zu überprüfen, ob Ihre Klasse gültig ist.

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

Durch wiederholte Verstöße können Sie Verstöße feststellen.

21
Artem

Sie müsste einen Validator anrufendie Entität, wenn Sie sie validieren möchten. Dann erhalten Sie eine Gruppe von ConstraintViolationException, die im Grunde zeigt, für welches Feld/s Ihrer Entität eine Beschränkungsverletzung vorliegt und was genau darin lagVielleicht können Sie auch einen Teil des Codes freigeben, von dem Sie erwarten, dass er Ihre Entität überprüft.

Eine häufig verwendete Technik ist die Validierung in @PrePersist und die Rollback-Transaktion, wenn mehrere Datenänderungen während der Transaktion verwendet werden, oder andere Aktionen, wenn eine Validierungsausnahme abgerufen wird. 

Ihr Code sollte so aussehen:

@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
}
5
Nikola Yovchev

Sie können auch einfach @NonNull mit der lombok-Bibliothek verwenden, zumindest für das @NotNull-Szenario. Weitere Details: https://projectlombok.org/api/lombok/NonNull.html

4

in meinem Fall hatte ich eine benutzerdefinierte Einschränkung auf Klassenebene, die nicht aufgerufen wurde.

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

sobald ich meiner Klasse, entweder benutzerdefiniert oder Standard, eine Einschränkung auf Feldebene hinzugefügt habe, begann die Einschränkung auf Klassenebene zu funktionieren.

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

scheint mir fehlerhaftes Verhalten zu sein, aber leicht genug, um damit umzugehen, denke ich

1
ChetPrickles

Ich komme einige Jahre später hierher und konnte es dank atrain 's Kommentar oben beheben. In meinem Fall fehlte @Valid in der API, die das Objekt (in meinem Fall ein POJO) erhält, das mit @Size kommentiert wurde. Es hat das Problem gelöst.

Ich musste not keine zusätzliche Anmerkung hinzufügen, wie @Valid oder @NotBlank zu der mit @Size kommentierten Variable, nur diese Einschränkung in der Variablen und das, was ich in der API erwähnt habe ...

Pojo-Klasse:

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

API-Klasse:

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

Danke und Prost

0
xCovelus

für Methodenparameter können Sie Objects.requireNonNull () wie folgt verwenden: test(String str) { Objects.requireNonNull(str); } Dies wird jedoch nur zur Laufzeit geprüft und wirft eine NPE, wenn es null ist. Es ist wie eine Vorabprüfung. Aber das ist vielleicht das, wonach Sie suchen.

0
Edward

@Valid at Service Interface würde also nur für dieses Objekt funktionieren. Wenn Sie weitere Überprüfungen in der Hierarchie des ServiceRequest-Objekts haben, müssen Sie die Validierung möglicherweise explizit auslösen. So habe ich es gemacht:

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

}

Sie müssen auf Objektebene folgende Anmerkungen haben, wenn Sie die Validierung für dieses Objekt auslösen möchten.

@Valid
@NotNull
0
Akshay

Sie müssen @Valid zuzu jeder Mitgliedsvariablenhinzufügen, die auch ein Objekt war, das Validierungsbedingungen enthielt.

0
Chad

Eine gute Antwort von atrain , Aber vielleicht ist es die bessere Lösung, Ausnahmen zu erkennen, die eigenen HandlerExceptionResolver Und catch zu verwenden 

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

Dann können Sie Ihren Handler so sauber wie möglich halten ... Sie benötigen BindingResult, Model und SomeFormBean in myHandlerMethod nicht mehr.

0
PavelP