使用大猩猩的schema
package
The github.com/gorilla/schema http://www.gorillatoolkit.org/pkg/schemapackage正是为此而发明的。
您可以使用结构标签 https://stackoverflow.com/questions/10858787/what-are-the-uses-for-tags-in-go/30889373#30889373告诉如何将 URL 参数映射到结构体字段,schema
包寻找"schema"
标签键。
使用它:
import "github.com/gorilla/schema"
type Filter struct {
Offset int64 `schema:"offset"`
Limit int64 `schema:"limit"`
SortBy string `schema:"sortby"`
Asc bool `schema:"asc"`
//User specific filters
Username string `schema:"username"`
First_Name string `schema:"first_name"`
Last_Name string `schema:"last_name"`
Status string `schema:"status"`
}
func MyHandler(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
// Handle error
}
filter := new(Filter)
if err := schema.NewDecoder().Decode(filter, r.Form); err != nil {
// Handle error
}
// Do something with filter
fmt.Printf("%+v", filter)
}
使用编组和解组json
请注意,schema
包还将尝试将参数值转换为字段的类型。
如果该结构仅包含以下字段[]string
类型(或者你愿意做出妥协),你可以做到这一点,而无需schema
包裹。
Request.Form https://golang.org/pkg/net/http/#Request is a map
,映射自string
to []string
(因为一个参数可能会在 URL 中多次列出:
Form url.Values
And url.Values https://golang.org/pkg/net/url/#Values:
type Values map[string][]string
例如,如果您的Filter
结构看起来像这样:
type Filter struct {
Offset []string `json:"offset"`
Limit []string `json:"limit"`
SortBy []string `json:"sortby"`
// ..other fields
}
你可以简单地使用json https://golang.org/pkg/encoding/json/包到编组r.Form
,然后将其解组到您的结构中:
func MyHandler(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
// Handle error
}
data, err := json.Marshal(r.Form)
if err != nil {
// Handle error
}
filter := new(Fiter)
if err = json.Unmarshal(data, filter); err != nil {
// Handle error
}
fmt.Printf("%+v", filter)
}
此解决方案处理是否为同一参数名称提供多个值。如果你不关心多个值而只想要一个,那么你首先必须“转换”r.Form
to a map
与单string
值而不是[]string
.
它可能是这样的:
type Filter struct {
Offset string `json:"offset"`
Limit string `json:"limit"`
SortBy string `json:"sortby"`
// ..other fields
}
// Transformation from map[string][]string to map[string]string:
m := map[string]string{}
for k, v := range r.Form {
m[k] = v[0]
}
然后你就可以编组m
并将其解组到Filter
以同样的方式构造。