简介
gorilla/schema
是 gorilla 开发工具包中用于解决表单的库。它提供了一个简略的形式,能够很不便地将表单数据转为构造体对象,或者将构造体对象转为表单数据。
疾速应用
本文代码应用 Go Modules。
创立目录并初始化:
$ mkdir gorilla/schema && cd gorilla/schema
$ go mod init github.com/darjun/go-daily-lib/gorilla/schema
装置 gorilla/schema
库:
$ go get -u github.com/gorilla/schema
咱们还是拿后面登录的例子:
func index(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "Hello World")
}
func login(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
<form action="/login" method="post">
<label>Username:</label>
<input name="username"><br>
<label>Password:</label>
<input name="password" type="password"><br>
<button type="submit"> 登录 </button>
</form>
</body>
</html>`)
}
type User struct {
Username string `schema:"username"`
Password string `schema:"password"`
}
var (decoder = schema.NewDecoder()
)
func dologin(w http.ResponseWriter, r *http.Request) {r.ParseForm()
u := User{}
decoder.Decode(&u, r.PostForm)
if u.Username == "dj" && u.Password == "handsome" {http.Redirect(w, r, "/", 301)
return
}
http.Redirect(w, r, "/login", 301)
}
func main() {r := mux.NewRouter()
r.HandleFunc("/", index)
r.Handle("/login", handlers.MethodHandler{"GET": http.HandlerFunc(login),
"POST": http.HandlerFunc(dologin),
})
log.Fatal(http.ListenAndServe(":8080", r))
}
首先调用 schema.NewDecoder()
办法创立一个解码器 decoder
。在处理器中,先调用r.ParseForm()
解析表单数据,而后创立用户对象 u
,调用decoder.Decode(&u, r.PostForm)
通过表单数据填充该对象。
schema
应用反射来对应表单和构造体字段,咱们能够通过构造体标签来指定表单数据和字段的对应关系。
下面咱们将解码器作为一个包内的全局变量,因为 decoder
中会缓存一些构造体的元数据,并且它是并发平安的。
在 main
函数中,咱们创立了 gorilla/mux
路由,注册 /
根处理函数,应用中间件 handlers.MethodHandler
别离注册门路 /login
的 GET 和 POST 办法的处理器。而后调用 http.Handle("/", r)
将所有申请交由 gorilla/mux
路由解决。最初启动 Web 服务器承受申请。
编码
除了用于服务器解码表单数据外,schema
还可用于客户端,将构造体对象编码到表单数据中发送给服务器。咱们编写一个程序登录下面的服务器:
var (encoder = schema.NewEncoder()
)
func main() {client := &http.Client{}
form := url.Values{}
u := &User{
Username: "dj",
Password: "handsome",
}
encoder.Encode(u, form)
res, _ := client.PostForm("http://localhost:8080/login", form)
data, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(data))
res.Body.Close()}
与解码器的用法相似,首先调用 schema.NewEncoder()
创立一个编码器 encoder
,创立一个User
类型的对象 u
和表单数据对象 form
,调用encoder.Encode(u, form)
将u
编码到 form
中。而后应用 http.Client
的PostForm
办法发送申请。读取响应。
自定义类型转换
目前 schema
反对以下类型:
- 布尔类型:
bool
- 浮点数:
float32/float64
- 有符号整数:
int/int8/int32/int64
- 无符号整数:
uint/uint8/uint32/uint64
- 字符串:
string
- 构造体:由以上类型组成的构造体
- 指针:指向以上类型的指针
- 切片:元素为以上类型的切片,或指向切片的指针
有时候客户端会将一个切片拼成一个字符串传到服务器,服务器收到之后须要解析成切片:
type Person struct {
Name string `schema:"name"`
Age int `schema:"age"`
Hobbies []string `schema:"hobbies"`}
var (decoder = schema.NewDecoder()
)
func init() {decoder.RegisterConverter([]string{}, func(s string) reflect.Value {return reflect.ValueOf(strings.Split(s, ","))
})
}
func doinfo(w http.ResponseWriter, r *http.Request) {r.ParseForm()
p := Person{}
decoder.Decode(&p, r.PostForm)
fmt.Println(p)
fmt.Fprintf(w, "Name:%s Age:%d Hobbies:%v", p.Name, p.Age, p.Hobbies)
}
调用 decoder.RegisterConverter()
注册对应类型的转换函数,转换函数类型为:
func(s string) reflect.Value
行将申请中的字符串值转为满足咱们格局的值。
客户端申请:
type Person struct {
Name string `schema:"name"`
Age int `schema:"age"`
Hobbies string `schema:"hobbies"`
}
var (encoder = schema.NewEncoder()
)
func main() {client := &http.Client{}
form := url.Values{}
p := &Person{
Name: "dj",
Age: 18,
Hobbies: "Game,Programming",
}
encoder.Encode(p, form)
res, _ := client.PostForm("http://localhost:8080/info", form)
data, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(data))
res.Body.Close()}
客户端成心将 Hobbies
字段设置为字符串,发送申请。服务器将应用注册的 func (s string) reflect.Value
函数将该字符串切割为 []string
返回。
总结
schema
提供了一个简略的获取表单数据的形式,通过将数据填充到构造体对象中,咱们能够很不便的进行后续操作。schema
库比拟玲珑,对个性没太多要求的能够试试~
大家如果发现好玩、好用的 Go 语言库,欢送到 Go 每日一库 GitHub 上提交 issue😄
参考
- gorilla/schema GitHub:github.com/gorilla/schema
- Go 每日一库 GitHub:https://github.com/darjun/go-daily-lib
我
我的博客:https://darjun.github.io
欢送关注我的微信公众号【GoUpUp】,独特学习,一起提高~