Java Bean Validation (JSR303) vincoli che coinvolgono rapporto tra diverse proprietà del bean

StackOverflow https://stackoverflow.com/questions/1700295

Domanda

Dire che ho il seguente fagiolo java semplice:

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

Esiste un meccanismo in JSR 303 per creare un validatore personalizzato che convalida il vincolo che startDate deve essere prima endDate?

A me sembra essere un caso di uso comune, ma non riesco a trovare alcun esempio di questo tipo di vincolo multipla proprietà relationsship.

È stato utile?

Soluzione

Mi vengono in mente un paio di cose da provare.

È possibile creare un Constraint con un obiettivo di tipo in sé con un validatore appropriato:

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

Si potrebbe racchiudere un intervallo di date in un tipo e convalidare che:

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

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

  // etc.

Si potrebbe aggiungere una semplice proprietà che esegue il controllo:

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

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

Altri suggerimenti

Se stai usando Hibernate Validator in versione 4.1 o successiva è possibile utilizzare la @ScriptAssert vincolo insieme un linguaggio di scripting o di espressione per esprimere questo tipo di vincolo. Utilizzando JavaScript tuo esempio sarebbe simile a questa:

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

      private Date startDate;

      private Date endDate;

      //...
 } 

È possibile ottenere una sintassi ancora più compatto da la creazione di un vincolo personalizzato per il linguaggio di script di vostra scelta:

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

    private Date startDate;

    private Date endDate;

    //...
}

La risposta è un validatore livello di classe. È possibile definire vincoli personalizzati che è possibile inserire sulla classe di entità. Al momento la convalida si ottiene passato l'intera istanza nel metodo isValid (). È quindi possibile confrontare i vostri due date uno contro l'altro. Si veda anche la Hibernate Validator documentazione .

Poiché non v'è alcun modo per accedere al bean in una JSR 303 validatore, questo non è possibile.

Una soluzione potrebbe essere quella di fornire il proprio ConstraintValidatorContext ed estendere con un riferimento al bean che si sta convalidare. Ma non sono sicuro se è possibile modificare / annullare il rispettivo fabbrica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top