Revel框架会尽可能的将提交参数转换为期望的Go类型。这个从一个字符串提交参数转换为另一个类型被称为数据绑定
。
所有的请求参数被存放在一个Params
中,他包括:
URL路径参数
URL查询参数
表单值(或Multipart)
文件上传
这是Params
的定义:
type Params struct {
url.Values
Files map[string][]*multipart.FileHeader
}
嵌入的url.Values
提供了对简单值的访问,但开发者会发现非字符的值使用revel的数据绑定机制也非常容易。
Params
中的参数可以当作方法参数被Action接收。例如:
func (c AppController) Action(name string, ids []int, user User, img []byte) revel.Result {
...
}
在调用之前,revel会使用Binder
绑定器将提交的参数按名称转换为期望类型,如果转换不成功,将会用期望类型的0值代替。
绑定一个提交参数至期望的类型。
func (c SomeController) Action() revel.Result {
var ids []int
c.Params.Bind(&ids, "ids")
...
}
以下的数据类型支持开箱转换:
任意宽度的int整数
Bool类型
任意支持类型的指针
任意支持类型的切片
结构
time.Time 类型的日期与时间
*os.File, []byte, io.Reader, io.ReadSeeker 文件上传用到的
字符串值true
, on
, 与 1
都会被转为true
,否则被转为false
对于slices切片有两种支持: ordered 有序 与 unordered 无序.
有序:
?ids[0]=1
&ids[1]=2
&ids[3]=4
slice中的数据 []int{1, 2, 0, 4}
无序:
?ids[]=1
&ids[]=2
&ids[]=3
slice中的数据 []int{1, 2, 3}
只有struct切片将会使用有序切片
?user[0].Id=1
&user[0].Name=rob
&user[1].Id=2
&user[1].Name=jenny
struct使用.
符号来进行绑定
?user.Id=1
&user.Name=rob
&user.Friends[]=2
&user.Friends[]=3
&user.Father.Id=5
&user.Father.Name=Hermes
将会绑定为:
type User struct {
Id int
Name string
Friends []int
Father User
}
只有可导出字段才能被绑定。
revel内置了SQL标准时间字符串格式[“2006-01-02”, “2006-01-02 15:04”]
可以用如下方法添加其他的时间格式:
func init() {
revel.TimeFormats = append(revel.TimeFormats, "01/02/2006")
}
上传的文件可以被绑定为以下任意一种类型:
*os.File
[]byte
io.Reader
io.ReadSeeker
上传使用Go的multipart
来处理。上传的数据首先被保存在内存中,当大小超过10MB(默认)时,会保存至临时文件。
当绑定为os.File
类型时,revel会默认将上传的文件存储至临时文件,这样相比其他类型,效率比较低。
创建自定义Binder绑定器,只需要实现binder
接口并且注册。
func myBinder(params Params, name string, typ reflect.Type) reflect.Value {
...
}
func init() {
revel.TypeBinders[reflect.TypeOf(MyType{})] = myBinder
}