2009-11-09 6 views
21

Say mam następujący prosty java Fasola:Java Bean Validation (JSR303) ograniczenia obejmujące relacje między kilkoma właściwościami fasoli

class MyBean { 
    private Date startDate; 
    private Date endDate; 
    //setter, getters etc... 
} 

Czy istnieje mechanizm w JSR 303 w celu stworzenie własnego walidator który sprawdza ograniczenie że startDate musi być przed endDate?

Wydaje mi się, że jest to powszechny przypadek użycia, ale nie mogę znaleźć żadnych przykładów tego rodzaju wielokrotnych więzów relacji własności.

+1

szwy, że ktoś pisał kompletny przykład w jego blog: http://soadev.blogspot.de/2010/01/jsr-303-bean-validation_29.html – Ralph

Odpowiedz

27

Mogę wymyślić kilka rzeczy do wypróbowania.

Można by stworzyć Constraint z celem samego typu z odpowiednim walidator:

@ValidateDateRange(start="startDate", end="endDate") 
public class MyBean { 

Można hermetyzacji zakres dat w typie i potwierdzić, że:

public class DateRange {  
    private long start; 
    private long end; 

    public void setStart(Date start) { 
    this.start = start.getTime(); 
    } 

    // etc. 

mogłeś dodać prostą właściwość, która wykonuje czek:

public class MyBean { 
    private Date startDate; 
    private Date endDate; 

    @AssertTrue public boolean isValidRange() { 
    // TODO: null checks 
    return endDate.compareTo(startDate) >= 0; 
    } 
-5

Ponieważ nie ma sposobu dostępu do fasoli w walidatorze JSR 303, nie jest to możliwe.

Obejście problemu polegałoby na dostarczeniu własnego ConstraintValidatorContext i rozszerzeniu go o odniesienie do komponentu, który jest aktualnie sprawdzany. Ale nie jestem pewien, czy możesz zmienić/zastąpić fabrykę.

3

Odpowiedź to walidator na poziomie klasy. Możesz zdefiniować ograniczenia niestandardowe, które możesz umieścić w klasie encji. Podczas sprawdzania poprawności przekazujesz całą instancję do metody isValid(). Następnie możesz porównać swoje dwie daty ze sobą. Patrz także Hibernate Validator documentation.

10

Jeśli używasz Hibernate Validator w wersji 4.1 lub nowszej można użyć @ScriptAssert ograniczenie razem z językiem skryptowym lub ekspresyjnego wyrażania tego rodzaju ograniczeń. Przy użyciu JavaScript swój przykład wyglądałby następująco:

@ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)") 
public class CalendarEvent { 

     private Date startDate; 

     private Date endDate; 

     //... 
} 

można uzyskać jeszcze bardziej kompaktowy składni przez creating a custom constraint dla języka skryptowego swojego wyboru:

@JexlAssert("_.startDate < _.endDate") 
public class CalendarEvent { 

    private Date startDate; 

    private Date endDate; 

    //... 
} 
Powiązane problemy