Czy w Hibernacji Validator 4.x jest implementacja (lub inna implementacja) walidacji między polami? Jeśli nie, jaki jest najczystszy sposób na wdrożenie walidatora między polami?
Na przykład, w jaki sposób można użyć interfejsu API do sprawdzenia poprawności dwóch właściwości komponentu bean (takich jak sprawdzenie poprawności pola hasła zgodnego z polem weryfikacji hasła).
W adnotacjach oczekiwałbym czegoś takiego:
public class MyBean {
@Size(min=6, max=50)
private String pass;
@Equals(property="pass")
private String passVerify;
}
validation
hibernate-validator
bean-validation
Bradhouse
źródło
źródło
Odpowiedzi:
Każde ograniczenie pola powinno być obsługiwane przez odrębną adnotację walidatora, lub innymi słowy, nie jest sugerowana praktyka, aby sprawdzanie adnotacji walidacji jednego pola względem innych pól; Walidacja między polami powinna odbywać się na poziomie klasy. Ponadto JSR-303 Sekcja 2.2 preferowanym sposobem wyrażania wielu walidacji tego samego typu jest lista adnotacji. Umożliwia to określenie komunikatu o błędzie dla każdego dopasowania.
Na przykład sprawdzanie poprawności wspólnego formularza:
Adnotacja:
The Validator:
źródło
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()).addNode(secondFieldName).addConstraintViolation().disableDefaultConstraintViolation();
Daje możliwość podświetlenia właściwego pola (jeśli tylko JSF by go wspierało).BeanUtils.getProperty
zwraca ciąg. Ten przykład prawdopodobnie miał użyć,PropertyUtils.getProperty
który zwraca obiekt.Sugeruję inne możliwe rozwiązanie. Być może mniej elegancki, ale łatwiejszy!
isValid
Metoda jest wywoływana przez walidator automatycznie.źródło
@AssertTrue
metod? Czy obowiązuje jakaś konwencja nazewnictwa?Dziwię się, że to nie jest dostępne po wyjęciu z pudełka. W każdym razie tutaj jest możliwe rozwiązanie.
Utworzyłem walidator na poziomie klasy, a nie na poziomie pola, jak opisano w pierwotnym pytaniu.
Oto kod adnotacji:
I sam walidator:
Zauważ, że użyłem MVEL do sprawdzenia właściwości sprawdzanego obiektu. Można to zastąpić standardowymi interfejsami API refleksji lub, jeśli jest to konkretna sprawdzana klasa, same metody akcesora.
Adnotacji @Matches można następnie użyć na fasoli w następujący sposób:
Jako zastrzeżenie napisałem to w ciągu ostatnich 5 minut, więc prawdopodobnie nie usunąłem jeszcze wszystkich błędów. Zaktualizuję odpowiedź, jeśli coś pójdzie nie tak.
źródło
W Hibernacji Validator 4.1.0. Polecam użycie @ScriptAssert . Wyjście z JavaDoc:
Uwaga: ocena jest wykonywana przez „ silnik ” skryptowy działający na maszynie wirtualnej Java, dlatego po stronie serwera Java, a nie po stronie klienta, jak stwierdzono w niektórych komentarzach.
Przykład:
lub z krótszym aliasem i zerowo bezpieczny:
lub z Javą 7+ null-safe
Objects.equals()
:Niemniej jednak nie ma nic złego w rozwiązaniu sprawdzania poprawności na poziomie klasy niestandardowej @Matches .
źródło
Sprawdzanie poprawności między polami można wykonać, tworząc niestandardowe ograniczenia.
Przykład: - Porównaj hasło i potwierdź pola Hasło instancji użytkownika.
CompareStrings
StringComparisonMode
CompareStringsValidator
ConstraintValidatorHelper
Użytkownik
Test
Wynik
Message:- [Password, ConfirmPassword] must be equal.
Używając ograniczenia walidacji CompareStrings, możemy również porównywać więcej niż dwie właściwości i mieszać dowolną z czterech metod porównywania ciągów.
ColorChoice
Test
Wynik
Message:- Please choose three different colors.
Podobnie możemy mieć ograniczenia walidacji między polami CompareNumbers, CompareDates itp.
PS Nie testowałem tego kodu w środowisku produkcyjnym (chociaż testowałem go w środowisku deweloperskim), więc rozważ ten kod jako wydanie Milestone. Jeśli znajdziesz błąd, napisz miły komentarz. :)
źródło
Wypróbowałem przykład Alberthovena (hibernacja-walidator 4.0.2.GA) i otrzymałem ValidationException: „Metody z adnotacjami muszą być zgodne z konwencją nazewnictwa JavaBeans. match () nie. ”też. Po zmianie nazwy metody z „dopasuj” na „isValid” to działa.
źródło
Jeśli korzystasz z Spring Framework, możesz do tego użyć Spring Expression Language (SpEL). Napisałem małą bibliotekę, która zapewnia walidator JSR-303 oparty na SpEL - dzięki temu sprawdzanie poprawności w wielu polach jest dziecinnie proste! Spójrz na https://github.com/jirutka/validator-spring .
Spowoduje to sprawdzenie długości i równości pól hasła.
Możesz również łatwo to zmodyfikować, aby zweryfikować pola hasła tylko wtedy, gdy oba nie są puste.
źródło
Podoba mi się pomysł Jakuba Jirutki, aby użyć Spring Expression Language. Jeśli nie chcesz dodawać kolejnej biblioteki / zależności (zakładając, że już korzystasz z Springa), oto uproszczona implementacja jego pomysłu.
Ograniczenie:
Walidator:
Zastosuj w ten sposób:
źródło
Nie mam reputacji komentowania pierwszej odpowiedzi, ale chciałem dodać, że dodałem testy jednostkowe dla zwycięskiej odpowiedzi i mam następujące uwagi:
źródło
Bardzo ładne rozwiązanie bradhouse. Czy jest jakiś sposób na zastosowanie adnotacji @Matches do więcej niż jednego pola?
EDYCJA: Oto rozwiązanie, które wymyśliłem, aby odpowiedzieć na to pytanie, zmodyfikowałem Ograniczenie, aby zaakceptować tablicę zamiast jednej wartości:
Kod adnotacji:
I wdrożenie:
źródło
Musisz to nazwać jawnie. W powyższym przykładzie bradhouse dał ci wszystkie kroki, aby napisać niestandardowe ograniczenie.
Dodaj ten kod do klasy dzwoniącego.
w powyższym przypadku byłoby
źródło
Wypróbuj Oval: http://oval.sourceforge.net/
Wygląda na to, że obsługuje OGNL, więc może możesz to zrobić w bardziej naturalny sposób
źródło
Jesteście niesamowici. Naprawdę niesamowite pomysły. Najbardziej lubię te Alberthovena i McGina , więc postanowiłem połączyć oba te pomysły. I opracuj ogólne rozwiązanie dla wszystkich przypadków. Oto moje proponowane rozwiązanie.
źródło
Dokonałem niewielkiej adaptacji w rozwiązaniu Nicko, aby nie trzeba było używać biblioteki Apache Commons BeanUtils i zastąpić ją rozwiązaniem dostępnym już wiosną, dla tych, którzy używają tego, ponieważ mogę być prostszy:
źródło
Rozwiązanie z pytaniem: jak uzyskać dostęp do pola opisanego we właściwości adnotacji
I jak go używać ...? Lubię to:
źródło