Play framework 表格提交
更新日期:
環境設定
- PlayFramework: v2.4.6
- scala : 2.11.6
先import 以下1
2
3import play.api.data._
import play.api.data.Forms._
import play.api.data.format.Formats._
先定義一個case class
case class 的作用是用來encapsulate 提交的資料為一個object, 正式名稱為Algebraic data type , 將data 定義為不同結溝和不同value,以下例子為Haskell
data Bool = False | True
data Maybe a = Nothing | Just a
an algebraic data type is a kind of composite type, i.e. a type formed by combining other types
回到play中,加入case class User(name: String, password: String)
這定義User 有兩個String field, 當中有當中有name 和password,是否很像c中的struct, 但scala 中的Algebraic data type不只case class, Option
也是其中一種
然後定義一個Form
定義一個form 實現如何把form的parameter blind to the case class
1 | val userForm = Form( |
- 表格中的”name” 為String
- 表格中的”password” 為String
apply 和unapply 的作用
1 | scala> User("jason", "password") |
User.apply
是用作創建新instance of the UserUser.unapply
是用作extract 資料,用作patten matching (match & case)
1 | // when u is a User |
GET Request
1 | def login = Action(parse.form(userForm)) { request => |
request.body 裡就是User了
Result (content type: text/plain)
Got: request.body.class: class controllers.UserController$User User name: jason, User password: text
Test with Curl
1 | curl --data http://localhost:9000/api/user/login2 \ |
POST Request
1 | def login2 = Action(parse.urlFormEncoded) { implicit request => |
比較麻煩 需要把mapping 轉做form然後再map做base class
Test with curl
1 | curl -H "Content-Type:application/x-www-form-urlencoded" \ |
Nested field
可以定義一個field 作為list
or seq
但需要跟隨一定規則定義html name
field
例如在文件中1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25val contactForm: Form[Contact] = Form(
// Defines a mapping that will handle Contact values
mapping(
"firstname" -> nonEmptyText,
"lastname" -> nonEmptyText,
"company" -> optional(text),
// Defines a repeated mapping
"informations" -> seq(
mapping(
"label" -> nonEmptyText,
"email" -> optional(email),
"phones" -> list(
text verifying pattern("""[0-9.+]+""".r, error="A valid phone number is required")
)
),
"mynickname" -> mapping(
"primaryscl" -> text,
"secondaryscl" -> text
)
(ContactInformation.apply)(ContactInformation.unapply)
)
)(Contact.apply)(Contact.unapply)
)
phones
在html 的name
為informations[0].phones1
2
3<input type="text" name="informations[0].phones">
(省略........)
<input type="text" name="informations[1].phones">
primaryscl
在html 的name
為mynickname.primaryscl1
2<input type="text" name="mynickname.primaryscl">
<input type="text" name="mynickname.secondaryscl">