美文网首页Golang语言社区Go语言用例golang
go语言HTTP GET解析URL中的查询参数

go语言HTTP GET解析URL中的查询参数

作者: CodingCode | 来源:发表于2017-10-10 15:27 被阅读541次

    go语言HTTP GET解析URL中的查询参数

    经常我们会使用下面的逻辑来处理查询参数:

    func myHandler(w http.ResponseWriter, r *http.Request) {
        vars := r.URL.Query();
        a := vars["a"][0]
        ...
    }
    

    描述起来很简单,先获取Query对象,然后从Query对象里面根据名字解析到一个参数,再取其中的第一个元素值。

    下面我们仔细了解一下这几个数据对象:

    Query() 是什么对象

    语句 vars := r.URL.Query() 返回的vars是一个什么对象?

    Query函数的定义是是这样的:

    # net/url/url.go
    func (u *URL) Query() Values {
        v, _ := ParseQuery(u.RawQuery)
        return v
    }
    
    // Query is expected to be a list of key=value settings separated by
    // ampersands or semicolons. A setting without an equals sign is
    // interpreted as a key set to an empty value.
    func ParseQuery(query string) (Values, error) {
        m := make(Values)
        err := parseQuery(m, query)
        return m, err
    }
    
    // Values maps a string key to a list of values.
    // It is typically used for query parameters and form values.
    // Unlike in the http.Header map, the keys in a Values map
    // are case-sensitive.
    type Values map[string][]string
    

    这里我们可以看到Query()返回的Values实际上是一个map对象,这个map的key是字符串,value是字符串数组,正好是参数名到参数值数组的map关系,因为同一个参数名可以有多个值,所有参数值是一个字符串数组。例如:
    map["A"] = ["A1"]
    map["B"] = ["B1", "B2"]

    另外我们从代码看到vars不能为空nil值,虽然vars里面的成员可以为空,也就是说如果URL里面没有查询参数,那么vars的成员为空,即大小为0,但vars本身不为nil。

    如何解析参数值

    第一种原始方法遍历解析Query对象的成员。

      vars := r.URL.Query();
      a, ok := vars["a"]
      if !ok {
        fmt.Printf("param a does not exist\n");
      } else {
        fmt.Printf("param a value is [%s]\n", a);
      }
    

    几个例子:

    URL Result
    curl http://localhost:8080/api/service/get param a does not exist
    curl http://localhost:8080/api/service/get?a param a value is [[]]
    curl http://localhost:8080/api/service/get?a= param a value is [[]]
    curl http://localhost:8080/api/service/get?a=a1 param a value is [[a1]]
    curl http://localhost:8080/api/service/get?a=a2&a=a2 param a value is [[a1 a2]]

    从上述例子,我们可以看到a的类型是一个数组,即使是没有值,也是一个空数组。

    使用Get方法解析参数

    Get方法是专门用来处理只有一个参数的参数值,即当参数不存在是返回空串(""),当参数存在多个值时返回第一个值。
    Get方法的定义如下:

    // Get gets the first value associated with the given key.
    // If there are no values associated with the key, Get returns
    // the empty string. To access multiple values, use the map
    // directly.
    func (v Values) Get(key string) string {
        if v == nil {
            return ""
        }
        vs := v[key]
        if len(vs) == 0 {
            return ""
        }
        return vs[0]
    }
    

    重新验证上面的代码逻辑:

      vars := r.URL.Query();
      a := v.Get("a")
      fmt.Printf("param a value is [%s]\n", a);
    

    运行结果

    URL Result
    curl http://localhost:8080/api/service/get param a value is []
    curl http://localhost:8080/api/service/get?a param a value is []
    curl http://localhost:8080/api/service/get?a= param a value is []
    curl http://localhost:8080/api/service/get?a=a1 param a value is [a1]
    curl http://localhost:8080/api/service/get?a=a2&a=a2 param a value is [a1]

    可以看到如果参数不存在Get方法函数空串,当有多个参数时Get方法返回第一个值。
    相比较前面一种方法,Get不需要考虑空数组越界的问题,如果不存在就返回空串即可。

    相关文章

      网友评论

        本文标题:go语言HTTP GET解析URL中的查询参数

        本文链接:https://www.haomeiwen.com/subject/jewvyxtx.html