2010-09-11 15 views
19

play-framework için çek yazmaya ve iki farklı olasılık görmeye çalışıyorum. Her ikisini de tanımladım ve anlayışımın doğru olup olmadığını bilmek istiyorum (Yani bir sorudan ziyade bir öğretici, özellikle de bir şeyleri özlediğim herhangi bir yanıt almadığım için). Peki hangi olasılıklar var.Oynatma çerçevesi için özel kontroller/onaylama nasıl yazılır

  1. basit yol: class Check genişletme:
    Avantajları: Daha kolay, yazmak daha kolay
    Dezavantajları okumak için: Yalnızca mesajı tanımlayabilirsiniz, çek parametrelenmişse olamaz.
  2. Gelişmiş yol: OVal AbstractAnnotationCheck'a dayanan bir çek yazma.
    Avantajlar: Kontrolu parametrelendirebilir ve ek açıklama kullanmak için daha basit bir yöntem kullanabilirsiniz
    Dezavantajları: Biraz daha karmaşıktır.

Uygulamaya bir göz atmadan önce, iletileri açıklamak istiyorum. Mesajı her zaman doğrudan ayarlayabilirsiniz ya da bir mesaj özelliklerinde iletiyi yönlendirmek için bir tuş kullanabilirsiniz. Sonuncusu, temiz ve önerilen yoldur. Her doğrulama en az 1 parametre alır: Geçerli olmayan mülkün adı. Bu nedenle, doğrulama veya belirli parametreleri kontrol etme, her zaman, i> 1 olan %i$s ile belirtilir. İleti dizesinin biçimi Formatter kurallarına uygun olmalıdır, ancak tüm özelliklerin desteklenip desteklenmediğinden emin değilim. Bildiğim kadarıyla sadece% s,% d ve% f konumlandırma ile togeter desteklenmektedir. Yani dönüşümün sadece s, d veya f olabileceği %[argument_index$][flags]conversion.

Yani sağlayan @CheckWith(value=OptimisticLockingCheck.class, message="optimisticLocking.modelHasChanged") yakından bakmak için ek açıklamasıyla bu kontrol kullanmak

/** 
* Check with proof if the version of the current edited object is lesser 
* than the version in db. 
* Messagecode: optimisticLocking.modelHasChanged 
* Parameter: 1 the request URL. 
* Example-Message: The object was changed. <a href="%2$s">Reload</a> and do your changes again. 
* 
*/ 
static class OptimisticLockingCheck extends Check { 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public boolean isSatisfied(Object model, Object optimisiticLockingViolatedValue) { 
     //The comparision of version was made in the setter. Here 
     //we only have to check the flag. 
     if (((VersionedModel) model).optimisiticLockingViolated) { 
      final Request request = Request.current(); 
      //The following doesn't work in 1.0 but in 1.1 see https://bugs.launchpad.net/play/+bug/634719 
      //http://play.lighthouseapp.com/projects/57987-play-framework/tickets/116 
      //setMessage(checkWithCheck.getMessage(), request != null ? request.url : ""); 
      setMessage("optimisticLocking.modelHasChanged", request != null ? request.url : ""); 

     } 
     return !((VersionedModel) model).optimisiticLockingViolated; 
    } 
} 

: Ben iyimser kilitleme için benim modülünde kullanılan basit bir yol :

iki örneklere bir bakalım nasıl çalışır. Yapmamız gereken tek şey, sınıf play.data.validation.Check'i genişletmek ve isSatisfied yönteminin üzerine yazmaktır. Burada modelinizi ve özelliklerin değerini elde edersiniz. Yapmanız gereken tek şey, her şey yolundaysa ya da tersi durumda doğruysa geri dönmek. Bizim durumumuzda mevcut url'yi parametre olarak ayarlamak istiyoruz. Bu , setMessage() ile kolayca yapılabilir. Mesaj özelliklerinde ve parametrelerde tanımlanan mesajı veya mesaj anahtarını veriyoruz. Unutmayın, sadece 1 parametre verdik ama% 2 $ s ile anılacaktır, çünkü ilk parametre her zaman mülkün adıdır.

Şimdi oyunun Menzil-kontrol dayalı karmaşık bir yol: Birinci biz

@SuppressWarnings("serial") 
public class RangeCheck extends AbstractAnnotationCheck<Range> { 

    final static String mes = "validation.range"; 

    double min; 
    double max; 

    @Override 
    public void configure(Range range) { 
     this.min = range.min(); 
     this.max = range.max(); 
     setMessage(range.message()); 
    } 

    public boolean isSatisfied(Object validatedObject, Object value, OValContext context, Validator validator) { 
     requireMessageVariablesRecreation(); 
     if (value == null) { 
      return true; 
     } 
     if (value instanceof String) { 
      try { 
       double v = Double.parseDouble(value.toString()); 
       return v >= min && v <= max; 
      } catch (Exception e) { 
       return false; 
      } 
     } 
     if (value instanceof Number) { 
      try { 
       return ((Number) value).doubleValue() >= min && ((Number) value).doubleValue() <= max; 
      } catch (Exception e) { 
       return false; 
      } 
     } 
     return false; 
    } 

    @Override 
    public Map<String, String> createMessageVariables() { 
     Map<String, String> messageVariables = new TreeMap<String, String>(); 
     messageVariables.put("2-min", Double.toString(min)); 
     messageVariables.put("3-max", Double.toString(max)); 
     return messageVariables; 
    } 

} 

Tamam bence bir ek açıklama

/** 
* This field must be lower than and greater than. 
* Message key: validation.range 
* $1: field name 
* $2: min reference value 
* $3: max reference value 
*/ 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.FIELD, ElementType.PARAMETER}) 
@Constraint(checkWith = RangeCheck.class) 
public @interface Range { 

    String message() default RangeCheck.mes; 
    double min() default Double.MIN_VALUE; 
    double max() default Double.MAX_VALUE; 
} 

ve ardından onay ek açıklama don' tanımlamanız gerekir t açıklanmalıdır. Çeke bakalım. Bu durumda, net.sf.oval.configuration.annotation.AbstractAnnotationCheck uzatır. Ek açıklamaları aldığımız ve parametreleri kopyalayabileceğimiz bir konfigürasyon metodu yazmalıyız. O zaman çekimizi tanımlamalıyız. Diğer kontrolün uygulanmasına benzer bir yöntem. Bu yüzden sadece özel bir satır hariç, durumumuzu yazıp doğru ya da yanlış geri dönüyoruz! Eğer bir parametreli mesaj kullansaydık, metodumuzda requireMessageVariablesRecreation();'u aramalıyız. En azından createMessageVariables yöntemini geçersiz kılmalıyız. Burada biraz oyun bilgisi almalıyız (diğer tüm şeyler here olarak açıklanmıştır).Mesajlarınızı bir anahtar ve değerle bir haritaya koyarsınız, ancak sadece değerleri oynatır (çerçeve kodunda ValidCheck.java'a bakın). Yani pozisyona göre referans alınacaktır. Bu, HashMap yerine TreeMap kullanarak RangeCheck uygulamasının değiştirilmesini nedenidir. Ayrıca, anahtarların gönderilebilecekleri indeksle başlamasına izin verdim.

Bu yüzden umarım bu, oyun için özel doğrulama/kontrollerin nasıl yazılacağını daha açık hale getirir. Umarım tarif doğrudur. Bu soru benim anlayışım doğru mu?

+11

Dünyada ne hakkında konuşuyorsunuz? – user359996

+2

Oyunda özel çekler/onaylama nasıl yazılır. Play, http://www.playframework.org adresinde bulabileceğiniz bir çerçevedir. Senin için net olmayan şeyi anlamıyorum. – niels

+1

@niels Pratikte çalıştığınız şekilde çalışıyorsa, o zaman, evet, anlayışınız muhtemelen doğrudur. –

cevap

1

En azından ilk örneğinizin doğru yolda olduğu anlaşılıyor. Bunu, aşağıda verilen belgelere göre karşılaştırabilirsiniz, ancak örnekleminizin karmaşıklığından daha önce bahsettiğiniz karmaşıklığı kabul ediyorum.

http://www.playframework.org/documentation/1.1/validation#custom

Ben ikinci örnek üzerinde yorum çalma çerçevesi hakkında yeterince bilgimiz yok.

+0

Ekstra açıklama burada: http://www.playframework.org/documentation/1.2.3/validation#custom – Allan

İlgili konular