2012-07-09 26 views
7

JSR-303アノテーション(クラスレベル)とバリデーターの実装を使用して、プレイ2.0.1のカスタムフォームバリデーターを書き込もうとしました。フォームの検証後のPlayframework IllegalStateException

残念ながら、フォームを送信して検証が失敗すると、私はプレイのバグかもしれないIllegalStateExceptionを取得します(しかし、私は確認したいと思います)。

バリデータは以下のように宣言されたコントローラ・コードの

パート(フォームを受信するが提出)(明瞭化のためにのみ関連部分)関連するコード抽出物および問題の説明の下

public static Result save() { 
    Form<UserForm> userForm = form(UserForm.class).bindFromRequest(); 
    if (userForm.hasErrors()) { 
     return badRequest(createForm.render(userForm)); 
    } 
    UserForm user = userForm.get(); 

を見つけて下さい

public class FieldMatchValidator extends Validator<Object> 
    implements ConstraintValidator<FieldMatch, Object> 

検証アノテーションは

として宣言されています私はエラー

Caused by: java.lang.IllegalStateException: No value 
    at play.libs.F$None.get(F.java:217) ~[play_2.9.1.jar:2.0.1] 
    at play.data.Form.get(Form.java:363) ~[play_2.9.1.jar:2.0.1] 
    at controllers.UsersController.save(UsersController.java:40) ~[classes/:2.0.1] 
    at Routes$$anonfun$routes$1$$anonfun$apply$25$$anonfun$apply$26.apply(routes_routing.scala:189) ~[classes/:na] 
    at Routes$$anonfun$routes$1$$anonfun$apply$25$$anonfun$apply$26.apply(routes_routing.scala:189) ~[classes/:na] 
    at play.core.Router$HandlerInvoker$$anon$4$$anon$1.invocation(Router.scala:1086) ~[play_2.9.1.jar:2.0.1] 

言及がUserControllerのラインを取得するフォームを送信は、

@Target({TYPE, ANNOTATION_TYPE}) 
@Retention(RUNTIME) 
@Constraint(validatedBy = FieldMatchValidator.class) 
@play.data.Form.Display(name="constraint.fieldmatch") 
public @interface FieldMatch { 

    String message() default FieldMatchValidator.message; 
    Class<?>[] groups() default {}; 
    Class<? extends Payload>[] payload() default {}; 

= userForm.get()コールユーザーフォームのユーザです。

問題がどこにあるのか理解しようとすると、問題のコードがおそらく遊びのForm.javaにあることがわかりました。

フォームバインド(地図データ、文字列... allowedFields)が含まれています

if(result.hasErrors()) { 

    for(FieldError error: result.getFieldErrors()) { 
    ... 
    } 
return new Form(rootName, backedType, data, errors, None()); 
} 

とhasErrors()は何が起こることはresult.hasErrors()がtrueを返すことである

public boolean hasErrors() { 
    return !errors.isEmpty(); 
} 

です(クラスレベルで定義されたバリデータが失敗したため)、ビルドされたエラーリストは空のままです(result.getFieldErrors()は空のリストを返します)。

したがって、Form.hasErrors()はfalseを返しますが、Form.get()は失敗します。

何か不足していますか、実際はバグですか?

おかげに関して、

答えて

4

私は同じ問題を打つ、と私は把握することができませんでしたので、それがプレイです!バグや悪い使い方から、私は自分のFormクラスを作成して、既存のFormクラスを拡張しました。

あなたがここに私のクラスを見つけることができます。

Form<UserForm> userForm = new PatchedForm<UserForm>(UserForm.class).bindFromRequest(); 

そして、それは作る必要があります:https://gist.github.com/3074629

ただパッケージにこのクラスを置くが、その後、あなたのコントローラでは、あなたが使用する必要があります、patchと呼ばれますそれはそれは遊びのバグだ今

を;-)、私がプレイチームにバグとプル要求を満たすために持っている...

+0

ご意見ありがとうございます。私は、モデルレベルでの "検証"機能を実装する問題(演習のドキュメントで説明されているように)を「回避策」としました。回避策は実際には解決策ではありません。 –

+0

@JohnSmithこんにちはジョン。私は、新しいタイプのjava.time.LocalDateを使用してこれと同様の問題が発生している可能性があります。あなたはこれをどうやって行ったかを示す何かを投稿できますか?検証の実装に関する私が見つけることができるドキュメントは、はるかに古いバージョンのプレイでのみ有効です! – svaens

8

。あなたのフォームがバリデーションを実装している場合は、エラーがなくてもメソッドがnullを返すようにしてください。空のマップを返すと失敗します。