2010-09-11 22 views
19

Tôi cố gắng viết séc cho số play-framework và thấy hai khả năng khác nhau. Tôi mô tả cả hai và muốn biết nếu sự hiểu biết của tôi là chính xác (Vì vậy, nó là một hướng dẫn hơn là một câu hỏi, đặc biệt là vì tôi đã không nhận được bất kỳ phản ứng mà tôi bị mất một cái gì đó). Vì vậy, những khả năng tồn tại.Cách viết kiểm tra/xác thực tùy chỉnh cho khung chơi

  1. Cách đơn giản: Mở rộng lớp Check:
    Ưu điểm: Dễ dàng hơn để viết, dễ đọc
    Nhược điểm: Bạn không thể parametrized việc kiểm tra, bạn chỉ có thể xác định được thông báo.
  2. Cách nâng cao: Viết séc dựa trên OVal AbstractAnnotationCheck.
    Ưu điểm: Bạn có thể parametrized kiểm tra và có một đơn giản để sử dụng chú thích
    Nhược điểm: Một chút phức tạp hơn.

Trước khi chúng tôi xem xét triển khai, tôi muốn giải thích các thông báo. Bạn luôn có thể đặt tin nhắn trực tiếp hoặc sử dụng một khóa để tham chiếu tin nhắn trong một thuộc tính tin nhắn. Người cuối cùng là cách sạch hơn và được đề nghị. Mỗi xác thực nhận được tham số tối thiểu 1: Tên của thuộc tính không hợp lệ. Vì vậy, việc xác thực hoặc kiểm tra các tham số cụ thể luôn được gọi là %i$s trong đó i> 1. Định dạng của chuỗi tin nhắn phải tuân thủ các quy tắc của Formatter nhưng tôi không chắc liệu tất cả các tính năng có được hỗ trợ hay không. Theo như tôi biết chỉ% s,% d và% f được hỗ trợ kết hợp với định vị. Vì vậy, %[argument_index$][flags]conversion nơi chuyển đổi chỉ có thể là s, d hoặc f.

Cho phép có một cái nhìn vào hai ví dụ: Cách đơn giản tôi đã sử dụng trong mô-đun của tôi cho khóa lạc quan:

/** 
* 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; 
    } 
} 

Bạn sử dụng Kiểm tra này với chú thích @CheckWith(value=OptimisticLockingCheck.class, message="optimisticLocking.modelHasChanged")

Vì vậy, cho phép có một cái nhìn gần gũi hơn làm thế nào nó hoạt động. Điều duy nhất chúng ta phải làm là mở rộng class play.data.validation.Check và ghi đè phương thức isSatisfied. Ở đó bạn có được mô hình của bạn và giá trị của các thuộc tính. Tất cả những gì bạn phải làm là trả về true nếu mọi thứ đều ổn hoặc ngược lại. Trong trường hợp của chúng tôi, chúng tôi muốn đặt url hiện tại làm tham số. Bạn có thể dễ dàng thực hiện bằng cách gọi setMessage(). Chúng tôi cung cấp tin nhắn hoặc khóa tin nhắn được xác định trong thuộc tính tin nhắn và các thông số. Hãy nhớ rằng chúng tôi chỉ đưa ra 1 tham số nhưng được gọi là% 2 $ s, vì thông số đầu tiên luôn là tên của thuộc tính.

Bây giờ con đường phức tạp dựa trên Phạm vi kiểm tra của vở kịch: Đầu tiên chúng ta cần phải xác định một Chú thích

/** 
* 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; 
} 

và sau đó là Kiểm tra

@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; 
    } 

} 

OK Tôi nghĩ rằng chú thích don' t phải được giải thích. Chúng ta hãy nhìn vào kiểm tra. Trong trường hợp này, nó mở rộng net.sf.oval.configuration.annotation.AbstractAnnotationCheck. Chúng ta phải viết một phương thức cấu hình nơi chúng ta có được chú thích và có thể sao chép các tham số. Sau đó, chúng tôi phải xác định séc của chúng tôi. Tương tự như việc thực hiện kiểm tra khác. Vì vậy, chúng tôi chỉ viết điều kiện của chúng tôi và trả lại đúng hoặc sai, ngoại trừ một dòng đặc biệt! Nếu chúng ta sử dụng một thông điệp parametrized, chúng ta phải gọi requireMessageVariablesRecreation(); theo phương pháp của chúng ta. Ít nhất chúng ta phải ghi đè phương thức createMessageVariables. Ở đây chúng ta phải có được một trò chơi nhỏ-knowlegde (tất cả những thứ khác được mô tả là here).Bạn đặt tin nhắn của bạn vào một bản đồ với một khóa và giá trị, nhưng chơi chỉ mất các giá trị (xem ValidCheck.java trong mã khuôn khổ). Vì vậy, nó sẽ được tham chiếu theo vị trí. Đây là lý do tôi thay đổi việc triển khai RangeCheck bằng cách sử dụng TreeMap thay vì HashMap. Hơn nữa, tôi để các khóa bắt đầu với chỉ mục mà chúng có thể được giới thiệu.

Vì vậy, tôi hy vọng điều này giúp bạn hiểu rõ hơn cách viết xác thực/kiểm tra tùy chỉnh để phát. Tôi hy vọng mô tả là chính xác. Câu hỏi đặt ra là sự hiểu biết của tôi có đúng không?

+11

Bạn đang nói về cái quái gì? – user359996

+2

Howto viết kiểm tra/xác nhận tùy chỉnh trong khi chơi. Chơi là một khung mà bạn có thể tìm thấy ở đây http://www.playframework.org. Tôi không hiểu những gì không rõ ràng với bạn. – niels

+1

@niels Nếu nó hoạt động trong thực tế theo cách bạn mong đợi nó, sau đó, um, có sự hiểu biết của bạn có lẽ là chính xác. –

Trả lời

1

Ít nhất ví dụ đầu tiên của bạn dường như đang đi đúng hướng. Bạn có thể so sánh nó với tài liệu được cung cấp dưới đây, nhưng tôi giả sử từ sự phức tạp của ví dụ của bạn mà bạn đã đề cập đến nó.

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

Tôi không biết đủ về khuôn khổ chơi nhận xét về ví dụ thứ hai.

+0

Giải thích thêm ở đây: http://www.playframework.org/documentation/1.2.3/validation#custom – Allan

Các vấn đề liên quan