Play framework 2.0 -http表單提交和表單驗證

#處理表單提交

 

1.定義一個表單

 

play.data包下包含一些幫助處理Http表單數據提交和校驗的工具。最容易的處理表單提交的方式是定義一個play.data.Form來包裝現有的類:

Java代碼  收藏代碼
  1. public class User {  
  2.         public String email;  
  3.         public String password;  
  4.     }  
  5.     Form<User> userForm = form(User.class);  
 

 

注:底層數據綁定通過Spring的數據綁定實現。

 

這個表單可以生成一個User的結果值,值是HashMap<String,String>數據。

Java代碼  收藏代碼
  1. Map<String,String> anyData = new HashMap();  
  2.     anyData.put("email""[email protected]");  
  3.     anyData.put("password""secret");  
  4.   
  5.     User user = userForm.bind(anyData).get();  
 

如果你在作用域中有可用的請求,你可以直接從請求內容中綁定:

 

 

Java代碼  收藏代碼
  1. User user = userForm.bindFromRequest().get();  
 

 

 

2.定義約束

 

你可以添加額外的約束,在使用JSR-303(Bean驗證)註解時將會在綁定的過程中檢測約束。

Java代碼  收藏代碼
  1. public class User {  
  2.           
  3.         @Required  
  4.         public String email;  
  5.         public String password;  
  6.     }  
 

play.data.validation.Constraints類包含了若干內建的驗證註解。

你也可以通過在你的代碼中增加一個validate方法,自己定製一個驗證。

Java代碼  收藏代碼
  1. public class User {  
  2.           
  3.         @Required  
  4.         public String email;  
  5.         public String password;  
  6.           
  7.         public String validate() {  
  8.         if(authenticate(email,password) == null) {  
  9.             return "Invalid email or password";  
  10.         }  
  11.         return null;  
  12.         }  
  13.     }  
 

3.處理數據綁定錯誤

 

當然有驗證,就需要處理綁定時出現的錯誤。

Java代碼  收藏代碼
  1. if(userForm.hasErrors()) {  
  2.         return badRequest(form.render(userForm));  
  3.     } else {  
  4.         User user = userForm.get();  
  5.         return ok("Got user " + user);  
  6.     }  
 

 

4.初始化默認值填充表單

 

有時候你需要給表單填充默認值,典型的如:

Java代碼  收藏代碼
  1. userForm.fill(new User("[email protected]""secret"))  
 

5.註冊用戶自定義數據綁定器

 

萬一你要爲一個自定義對象定義一個與表單域之間的映射關係,你就需要註冊一個新的格式化工具(Formatter )。

 

例如爲JodaTime的本地時間對象定義一個映射:

Java代碼  收藏代碼
  1. Formatters.register(LocalTime.classnew Formatters.SimpleFormatter<LocalTime>() {  
  2.   
  3.         private Pattern timePattern = Pattern.compile("([012]?\\\\d)(?:[\\\\s:\\\\._\\\\-]+([0-5]\\\\d))?");   
  4.           
  5.         @Override  
  6.         public LocalTime parse(String input, Locale l) throws ParseException {  
  7.             Matcher m = timePattern.matcher(input);  
  8.             if (!m.find()) throw new ParseException("No valid Input",0);  
  9.             int hour = Integer.valueOf(m.group(1));  
  10.             int min = m.group(2) == null ? 0 : Integer.valueOf(m.group(2));  
  11.             return new LocalTime(hour, min);  
  12.         }  
  13.   
  14.         @Override  
  15.         public String print(LocalTime localTime, Locale l) {  
  16.             return localTime.toString("HH:mm");  
  17.         }  
  18.     });  
 

#使用表單模板幫助類(助手)

 

Play提供了若干幫助類幫助你渲染Html模板中的表單域。

 

1.創建<form>標籤

 

第一個幫助是創建<form>標籤。這是一個非常簡單的助手,它能根據你傳遞進來的檢索路徑自動的設置好action和method標籤參數。

Java代碼  收藏代碼
  1. @helper.form(action = routes.Application.submit()) {  
  2.           
  3.     }  
 

也可以傳遞一組額外的參數,它會被加到生成的html中:

Java代碼  收藏代碼
  1. @helper.form(action = routes.Application.submit(), 'id -> "myForm") {  
  2.           
  3.     }  
 

2.渲染一個input元素

 

views.html.helper包下有若干個input的助手,你給它們表單域,它們會展示相應的Html表單控件,有填充值,約束和錯誤信息。

Java代碼  收藏代碼
  1. @(myForm: Form[User])  
  2.   
  3.     @helper.form(action = routes.Application.submit()) {  
  4.           
  5.         @helper.inputText(myForm("username"))  
  6.           
  7.         @helper.inputPassword(myForm("password"))  
  8.           
  9.     }  
 

對於表單助手,你也可以指定額外的參數,它同樣會加到生成的Html中:

Java代碼  收藏代碼
  1. @helper.inputText(myForm("username"), 'id -> "username", 'size -> 30)  
 

注意:除了以下劃線"_"字符打頭的參數名稱外,所有額外的參數都會被加到生成的Html中。以下劃線打頭的名稱爲構造函數的參數域保留。

 

3.自己處理HTML input的創建

 

還有一個更通用的input輔助,讓您編寫想要的HTML結果:

Java代碼  收藏代碼
  1. @helper.input(myForm("username")) { (id, name, value, args) =>  
  2.         <input type="date" name="@name" id="@id" @toHtmlArgs(args)>  
  3.     }   
 

4.字段(或域)的構造

 

一個被渲染的字段不僅僅包含一個input標籤,它也需要<lable>和一大堆你的css框架裏用到的其他標籤來裝飾。

所有的input助手(輔助類)都隱含一個FieldConstructor ,用來處理這個問題。默認的構建器生成如下的html代碼:

Java代碼  收藏代碼
  1. <dl class="error" id="username_field">  
  2.         <dt><label for="username"><label>Username:</label></dt>  
  3.         <dd><input type="text" name="username" id="username" value=""></dd>  
  4.         <dd class="error">This field is required!</dd>  
  5.         <dd class="error">Another error</dd>  
  6.         <dd class="info">Required</dd>  
  7.         <dd class="info">Another constraint</dd>  
  8.     </dl>  
 

這個默認的域構造器支持額外的選項,你可以給input助手傳遞參數。

Java代碼  收藏代碼
  1. '_label -> "Custom label"  
  2.     '_id -> "idForTheTopDlElement"  
  3.     '_help -> "Custom help"  
  4.     '_showConstraints -> false  
  5.     '_error -> "Force an error"  
  6.     '_showErrors -> false  
 

 

4.Twitter bootstrap域構建

 

還有另外一個內建的字段構造器並用在Twitter Bootstrap上。

 

(引用:Bootstrap是一套用於開發網頁應用,符合HTML和CSS簡潔但優美規範的庫。Bootstrap由動態CSS語言Less寫成,在很多方面類似CSS框架Blueprint。經過編譯後,Bootstrap就是衆多CSS的合集。想要了解Bootstrap的細節,開發者請參考Twitter的官方指南和演示示例。)

 

要使用它只需要把它引入到當前作用域:

Java代碼  收藏代碼
  1. @import helper.twitterBootstrap._  
  

它會生成類似這樣的html代碼:

Java代碼  收藏代碼
  1. div class="clearfix error" id="username_field">  
  2.         <label for="username">Username:</label>  
  3.         <div class="input">  
  4.         <input type="text" name="username" id="username" value="">  
  5.         <span class="help-inline">This field is required!, Another error</span>  
  6.         <span class="help-block">Required, Another constraint</d</span>   
  7.         </div>  
  8.     </div>  
 

這個構造器和默認的構造器一樣有相同的選項設置。

 

5.寫自己的域構造器

 

你經常需要寫自己的域構造器,以這個例子作爲開始吧:

Java代碼  收藏代碼
  1. @(elements: helper.FieldElements)  
  2.   
  3.     <div class="@if(elements.hasErrors) {error}">  
  4.         <label for="@elements.id">@elements.label</label>  
  5.         <div class="input">  
  6.         @elements.input  
  7.         <span class="errors">@elements.errors.mkString(", ")</span>  
  8.         <span class="help">@elements.infos.mkString(", ")</span>   
  9.         </div>  
  10.     </div>  
 

注:這僅僅是個示例。你可以寫的更加複雜。也可以通過使用 @elements.field訪問原始域。

 

前面的域構造器可以這樣使用:

 

Java代碼  收藏代碼
  1. @implicitField = @{ FieldConstructor(myFieldConstructorTemplate.f) }  
  2.   
  3.     @inputText(myForm("username"))  
 

 

6.處理重複值

 

最後一個輔助類可以使得爲重複值生成input變的容易。假如你有這樣的表單定義。

Java代碼  收藏代碼
  1. val myForm = Form(  
  2.       tuple(  
  3.         "name" -> text,  
  4.         "emails" -> list(email)  
  5.       )  
  6.     )  
 

現在表單能包含多少email域你就的生成多少input。那麼你可以使用repeat輔助完成:

Java代碼  收藏代碼
  1. @inputText(myForm("name"))  
  2.   
  3.     @repeat(myForm("emails"), min = 1) { emailField =>  
  4.           
  5.         @inputText(emailField)  
  6.           
  7.     }  
 

即使相應表單數據是空,也可以使用min參數顯示域的最少數目。

 


發佈了3 篇原創文章 · 獲贊 1 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章