2013-07-04 8 views
12

Mam klasy Hibernate za walidacji adnotacji na niektórych obszarach (takich jak @NotNull i @Size(min = 4, max = 50), etc ...)Jak programowo wywołać ten sam sprawdzania poprawności, który działa na metodę @RequestMethod z parametrem @Valid w Spring?

public class MyClass { 

    Long id; 

    @NotEmpty 
    @Size(min = 4, max = 50) 
    String machineName; 

    @NotEmpty 
    @Size(min = 4, max = 50) 
    String humanName; 

    // Getters, setters, etc… 
} 

Mam też kontroler niestandardowy, który działa jako JSON API oraz Deserializator że JSON tworzy obiekty MyClass po wywołaniu metod API. W moim niestandardowego sterownika Mam metodę, aby utworzyć nowy obiekt tego typu:

@RequestMapping(method = RequestMethod.POST) 
public long createMyObject(@RequestBody @Valid MyClass newObj) { 
    // Create the object in the database 
    return newObj.getId(); 
} 

i innej metody, która aktualizuje istniejący obiekt

@RequestMapping(method = RequestMethod.PUT) 
public void updateMyObject(@RequestBody MyClass updatedObj) { 
    MyClass existingObj = // Get existing obj from DB by updatedObj.getId(); 

    // Do some secondary validation, such as making sure that a specific 
    // field remains unchanged compared to the existing instance 
    if (existingObj.getMachineName() != null && 
      !existingObj.getMachineName().equals(updatedObj.getMachineName())) { 
     throw new CannotChangeMachineNameException(); 
    } 
    else { 
     updatedObj.setMachineName(existingObj.getMachineName()); 
    } 

    // [HERE IS WHERE I WANT THE MAGIC TO HAPPEN] 

    // Save updatedObj to the database 
} 

Chociaż mogę używać @Valid w createMyObject, nie mogę używać to w updateMyObject, ponieważ nasza implementacja interfejsu API wymaga, aby nazwa komputera pozostała niezmieniona - użytkownicy mogą wywoływać interfejs API za pomocą obiektu JSON, który całkowicie wyklucza nazwę MachineName lub zapełnia ją taką samą wartością, jaka istnieje w bazie danych. *

Przed zapisaniem zaktualizowanego obiektu do bazy danych chcę wywołać ten sam sprawdzacz, który spowodowałby wywołanie adnotacji @Valid. Jak mogę znaleźć ten weryfikator i użyć go?

+1

Myślę, że można używać grup walidacji. Wszystkie walidacje inne niż "@ NotNull" w 'machineName' (lub niestandardowym walidatorze, który porównuje starą i nową nazwę) znajdują się w domyślnej grupie i pozostały walidator należy do grupy' Update'. Użyj obu grup w metodzie "updateMyObject". Zobacz http://docs.jboss.org/hibernate/validator/5.0/reference/en-US/html/chapter-groups.html#d0e2595 –

Odpowiedz

6

Nic nie mówi, że musisz używać @Valid tylko w swoich metodach kontrolera. Dlaczego nie zrobić metody sprawdzania poprawności, która akceptuje parametr, który opisujesz jako @Valid, a następnie po prostu zwróć ten sam parametr.

Jak to:

public Book validateBook(@Valid Book book) { 
    return book; 
} 

Wygląda alternatywą byłoby użyć pakiet walidacji Hibernate. Here's it's documentation.

Zasadniczo masz Validator od A ValidationFactory, a następnie za pomocą walidatora takiego:

@Test 
    public void manufacturerIsNull() { 
     Car car = new Car(null, "DD-AB-123", 4); 

     Set<ConstraintViolation<Car>> constraintViolations = 
      validator.validate(car); 

     assertEquals(1, constraintViolations.size()); 
     assertEquals("may not be null", constraintViolations.iterator().next().getMessage()); 
} 
+1

Dzięki! To doprowadziło mnie wystarczająco blisko do odpowiedzi - pierwsza metoda nie działała, zrobiłem coś podobnego do drugiej metody: Set > errors = Validation.buildDefaultValidatorFactory(). GetValidator(). Validate (updatedObj); // Doszedłem do tego z dokumentacji, którą wskazałeś – daniel

Powiązane problemy