2012-07-09 47 views
7

我嘗試使用JSR-303註釋(類級別)和驗證器實現爲Play 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> 

驗證註解聲明爲

@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.get();

試圖瞭解問題出在哪裏,我發現有問題的代碼可能在播放的Form.java中。

表單綁定(地圖數據,字符串... 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

我打的是同樣的問題,因爲我沒能搞清楚的是它是一個遊戲!錯誤或不好的用法,我最終通過擴展現有的Form類來編寫我自己的Form類。

你可以找到我的課在這裏:https://gist.github.com/3074629

只要把這個類在一個名爲patch包,那麼,在你的控制器,你將不得不使用:

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

它應該做它;-)

現在,我必須填寫錯誤和拉請求播放團隊...

+0

感謝您的評論。我「模擬」了在模型級實現「驗證」功能的問題(如遊戲文檔中所述)。實際上只是一種解決方法,並非真正的解決方案。 – 2012-07-10 19:58:53

+0

@約翰史密斯嗨約翰。我想我可能會遇到類似的問題,使用更新的類型java.time.LocalDate。你能發表一些展示你如何做到的事嗎?我可以找到關於實現驗證的任何文檔,只適用於較舊版本的遊戲! – svaens 2015-12-30 20:14:25

8

這是玩的錯誤。如果您的表單實現了驗證,那麼只要確保該方法在沒有錯誤時返回null。如果你返回一個空的地圖,那麼它將失敗