如何将所有的GET请求查询参数放到Go中的结构中? [英] How to get all GET request query parameters into a structure in Go?

查看:143
本文介绍了如何将所有的GET请求查询参数放到Go中的结构中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我想要将查询参数转换为Go中的结构,例如我有这样的结构:

  type Filter struct $ {
Offset int64`json:offset`
Limit int64`json:limit`
SortBy string`json:sortby`
Asc bool`json: asc`

//用户特定的过滤器
用户名字符串`json:username`
First_Name字符串`json:first_name`
Last_Name字符串` json:last_name`
状态字符串`json:status`
}

我有发送get请求时可以指定的可选参数,它们是 Offset Limit SortBy Asc 用户名 First_Name Last_Name 状态



如果这些参数是在body中发送的,那么我会这样做:

  b,err:= ioutil .ReadAll(r.Body)
if err!= nil {

log.WithFields(logFields).Errorf(阅读正文消息:失败:%v,错误)

返回
}

var filter Filter
err = json.Unmarshal(b,& filter)

但我不能在 GET 请求中发送主体,那么解决方案是什么,而不是单独获取每个参数,然后将它们放入结构中?

$ b $使用gorilla的模式软件包

github.com/gorilla/schema 包就是为此而发明的。

您可以使用 struct tags 告诉如何将URL参数映射到结构字段, schema 包寻找 $ b

使用它: pre> 即时通讯端口github.com/gorilla/schema

类型Filter结构{
Offset int64`schema:offset`
限制int64`schema:limit`
SortBy string`schema:sortby`
Asc bool`schema:asc`

//用户特定的过滤器
用户名字符串`schema:username`
First_Name字符串`schema:first_name`
Last_Name字符串`schema:last_name`
状态字符串`schema:status`
}

func MyHandler(w http.ResponseWriter,r * http.Request){
if err:= r.ParseForm(); err!= nil {
//处理错误
}

filter:= new(Filter)
if err:= schema.NewDecoder()。Decode(filter ,r.Form); err!= nil {
//处理错误
}

//用
做一些事fmt.Printf(%+ v,filter)



$ b

使用 json 进行封送和反编组>



请注意, schema 包也会尝试将参数值转换为字段的类型。



如果结构只包含 [] string 类型的字段(或者您愿意做出妥协),那么您可以在没有 schema 包的情况下执行。

/ net / http /#Requestrel =nofollow noreferrer> Request.Form map ,从字符串 []字符串映射(因为一个参数可能会在URL中多次列出: p>

 表单url.Values 

以及 url.Values

 类型值map [string] [] string 

例如,如果您的 Filter struct看起来像这样:

 类型Filter结构{
Offset []字符串`json:offset`
限制[] string`json:limit`
SortBy [] string` json:sortby`
// ..其他字段
}

您只需使用 json 打包到 r.Form ,然后将它解组到您的结构中:

  func MyHandler(w http.ResponseWriter,r * http.Request){
if err:= r.ParseForm(); err!= nil {
//处理错误
}
data,err:= json.Marshal(r.Form)
if err!= nil {
/ /处理错误
}
filter:= new(Fiter)
if err = json.Unmarshal(data,filter); err!= nil {
//处理错误
}
fmt.Printf(%+ v,过滤器)
}

此解决方案处理是否为相同参数名称提供了多个值。如果你不关心多个值并且只需要一个值,那么首先必须将 r.Form 转换为 map 单个字符串值而不是 []字符串



这是它的样子:

 类型Filter结构{
偏移字符串`json: $ offset
限制字符串`json:limit`
SortBy字符串`json:sortby`
// ..其他字段
}

//从map [string] [] string到map [string]的转换string:
m:= map [string] string {}
for k,v:= range r.Form {
m [k] = v [0]
}

然后你可以编组 m 并以同样的方式将它解组到 Filter 结构中。


Hi I want to transform get query parameters into a structure in Go, for example I have this structure:

type Filter struct {
    Offset int64  `json:"offset"`
    Limit  int64  `json:"limit"`
    SortBy string `json:"sortby"`
    Asc    bool   `json:"asc"`

    //User specific filters
    Username   string `json:"username"`
    First_Name string `json:"first_name"`
    Last_Name  string `json:"last_name"`
    Status     string `json:"status"`
}

And I have the optional parameters that the user can specify when sending a get request which are Offset, Limit, SortBy, Asc, Username, First_Name, Last_Name, Status.

If those parameters were sent in the body then I would do this:

b, err := ioutil.ReadAll(r.Body)
if err != nil {

    log.WithFields(logFields).Errorf("Reading Body Message:failed:%v", err)

    return
}

var filter Filter
err = json.Unmarshal(b, &filter)

But I can't send body in a GET request so what is the solution instead of getting each parameter alone and then putting them into a structure?

解决方案

Using gorilla's schema package

The github.com/gorilla/schema package was invented exactly for this.

You can use struct tags to tell how to map URL parameters to struct fields, the schema package looks for the "schema" tag keys.

Using it:

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)
}

Marshaling and unmarshaling using json

Note that the schema package will also try to convert parameter values to the type of the field.

If the struct would only contain fields of []string type (or you're willing to make that compromise), you can do that without the schema package.

Request.Form is a map, mapping from string to []string (as one parameter may be listed multiple times in the URL:

Form url.Values

And url.Values:

type Values map[string][]string

So for example if your Filter struct would look like this:

type Filter struct {
    Offset []string `json:"offset"`
    Limit  []string `json:"limit"`
    SortBy []string `json:"sortby"`
    // ..other fields
}

You could simply use the json package to marshal r.Form, then unmarshal it into your struct:

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)
}

This solution handles if multiple values are provided for the same parameter name. If you don't care about multiple values and you just want one, you first have to "transform" r.Form to a map with single string values instead of []string.

This is how it could look like:

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]
}

And then you can marshal m and unmarshal into it into the Filter struct the same way.

这篇关于如何将所有的GET请求查询参数放到Go中的结构中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆