8

JSR-303 アノテーション (クラスレベル) とバリデーターの実装を使用して、play 2.0.1 用のカスタムフォームバリデーターを作成しようとしました。

残念ながら、フォームを送信して検証に失敗すると、プレイのバグである可能性がある 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>

検証アノテーションは次のように宣言されます。

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

フォームを送信するとエラーが発生します

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]

上記の UsersController の行は、 UserForm user = userForm.get(); の呼び出しです。

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

Form bind(Map data, String... allowedFields) には以下が含まれます。

if(result.hasErrors()) {

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

そして hasErrors() は

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

何が起こるかというと、result.hasErrors() は true を返しますが (クラス レベルで定義されたバリデータが失敗したため)、構築されたエラー リストは空のままです (result.getFieldErrors() は空のリストを返します)。

結果として、 Form.hasErrors() は false を返しますが、 Form.get() は失敗します。

何か足りないのですか、それとも実際にはバグですか?

よろしくお願いいたします。

4

2 に答える 2

9

プレイ中のバグです。フォームが検証を実装している場合は、エラーがない場合は常にメソッドが null を返すようにしてください。空のマップを返すと失敗します

于 2013-03-15T17:09:43.503 に答える
4

私は同じ問題にぶつかりましたが、理解できなかったので、それはプレイです! バグか私の悪い使い方でForm、既存のクラスを拡張して独自のクラスを作成することになりましたForm

ここで私のクラスを見つけることができます: https://gist.github.com/3074629

このクラスを というパッケージに入れるだけpatchで、コントローラーで次を使用する必要があります。

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

そしてそれはそれを作るべきです;-)

さて、Play チームにバグとプル リクエストを提出する必要があります...

于 2012-07-09T06:38:12.670 に答える