2012-07-09 4 views
7

J'ai essayé d'écrire un validateur de formulaire personnalisé pour le jeu 2.0.1 en utilisant des implémentations d'annotations JSR-303 (de niveau classe) et de validateur.Playframework IllegalStateException après la validation du formulaire

Malheureusement, lorsque je soumets le formulaire et la validation échoue, je reçois une IllegalStateException qui pourrait être un bug de jeu (mais je voudrais confirmer).

S'il vous plaît trouverez ci-dessous les extraits de code pertinents et la description du problème (uniquement des pièces pertinentes pour des raisons de clarté)

partie du code du contrôleur (réception du formulaire soumettre)

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

Le validateur est déclarée comme

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

L'annotation de validation est déclarée comme

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

Envoi de la forme i obtenir l'erreur

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] 

La ligne mentionnée de UsersController est l'utilisateur du formulaire utilisateur d'appel = userForm.get();

En essayant de comprendre où le problème est, j'ai trouvé que le code incriminé est probablement en jeu. Form.java.

La liaison de formulaire (données cartographiques, String ... allowedFields) contient:

if(result.hasErrors()) { 

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

Et les hasErrors() est

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

Ce qui se passe est que result.hasErrors() renvoie true (parce que le validateur défini au niveau de la classe a échoué), mais la liste des erreurs générées reste vide (result.getFieldErrors() renvoie une liste vide). En conséquence, Form.hasErrors() renvoie false mais Form.get() échoue.

Ai-je raté quelque chose ou est-ce vraiment un bug?

Merci et salutations,

Répondre

4

je frappe la même question, et que je ne suis pas en mesure de comprendre est c'est un jeu! bug ou une mauvaise utilisation de moi, j'ai fini par écrire ma propre classe Form en étendant la classe existante Form.

Vous pouvez trouver ma classe ici: https://gist.github.com/3074629

Il suffit de mettre cette classe dans un paquet appelé patch, puis, dans votre contrôleur, vous devrez utiliser:

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

Et il devrait faire ;-) il

maintenant, je dois remplir un bug et une demande de traction à l'équipe Play ...

+0

Merci pour votre commentaire. Je "contourne" le problème en implémentant la fonction "valider" au niveau du modèle (comme expliqué dans la documentation de jeu). Seulement une solution de contournement réellement, pas vraiment une solution. –

+0

@JohnSmith Salut John. Je pense que je peux avoir un problème similaire avec ceci en utilisant le nouveau type java.time.LocalDate. Pouvez-vous poster quelque chose montrant comment vous avez fait cela? Toute documentation que je peux trouver concernant la mise en œuvre de la validation ne semble valable que pour une version plus ancienne du jeu! – svaens

8

il est un bug sur le jeu. Si votre formulaire implémente validate, assurez-vous que la méthode renvoie null lorsqu'il n'y a pas d'erreur.Si vous retournez une carte vide alors elle échouera

Questions connexes