url.Values中的嵌套值

huangapple go评论73阅读模式
英文:

Nested values in url.Values

问题

我正在开发一个API客户端,需要能够使用client.PostForm请求发送一个嵌套的JSON结构。我遇到的问题是:

reqBody := url.Values{
    "method": {"server-method"},
    "arguments": {
        "download-dir": {"/path/to/downloads/dir"},
        "filename":     {variableWithURL},
        "paused":       {"false"},
    },
}

当我尝试go build时,出现以下错误:

./transmission.go:17: syntax error: unexpected :, expecting }
./transmission.go:24: non-declaration statement outside function body
./transmission.go:26: non-declaration statement outside function body
./transmission.go:27: non-declaration statement outside function body
./transmission.go:29: non-declaration statement outside function body
./transmission.go:38: non-declaration statement outside function body
./transmission.go:39: syntax error: unexpected }

我想知道在这种情况下创建嵌套值的正确方法是什么。提前感谢!

英文:

I'm working on an API client and I need to be able to send a nested JSON structure with a client.PostForm request. The issue I'm encountering is this:

reqBody := url.Values{
	"method": {"server-method"},
	"arguments": {
		"download-dir": {"/path/to/downloads/dir"},
		"filename":     {variableWithURL},
		"paused":       {"false"},
	},
}

When I try to go build this, I get the following errors:

./transmission.go:17: syntax error: unexpected :, expecting }
./transmission.go:24: non-declaration statement outside function body
./transmission.go:26: non-declaration statement outside function body
./transmission.go:27: non-declaration statement outside function body
./transmission.go:29: non-declaration statement outside function body
./transmission.go:38: non-declaration statement outside function body
./transmission.go:39: syntax error: unexpected }

I'm wondering what the correct way to created a nested set of values in this scenario. Thanks in advance!

答案1

得分: 3

你没有正确使用url.Values,根据源代码(url包,url.go):

// Values将字符串键映射到值列表。
// 它通常用于查询参数和表单值。
// 与http.Header映射中的键不同,
// Values映射中的键区分大小写。
type Values map[string][]string

但是arguments不符合这个定义,因为arguments的对象不是一个字符串数组。

英文:

You are not using properly the url.Values, according to the source code (url package, url.go):

// 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

But arguments is not compliant with the definition because the object of arguments is not an array of strings.

答案2

得分: 3

我能自己解决这个问题!答案是将所有东西都结构化!

type Command struct {
    Method      string      `json:"method,omitempty"`
    Arguments   Arguments   `json:"arguments,omitempty"`
}

type Arguments struct {
    DownloadDir string      `json:"download-dir,omitempty"`
    Filename    string      `json:"filename,omitempty"`
    Paused      bool        `json:"paused,omitempty"`
}

然后,在创建你的 PostForm 时:

jsonBody, err := json.Marshal(reqBody) // reqBody 是一个 Command

if err != nil {
    return false
}

req, err := http.NewRequest("POST", c.Url, strings.NewReader(string(jsonBody)))

希望这能帮到你!

英文:

I was able to figure this out on my own! The answer is to struct all-the-things!

type Command struct {
    Method 			string		`json:"method,omitempty"`
    Arguments 		Arguments 	`json:"arguments,omitempty"`
}

type Arguments struct {
    DownloadDir 	string 		`json:"download-dir,omitempty"`
    Filename		string		`json:"filename,omitempty"`
    Paused			bool		`json:"paused,omitempty"`
}

Then, when creating your PostForm:

jsonBody, err := json.Marshal(reqBody) // reqBody is a Command

if (err != nil) {
	return false
}

req, err := http.NewRequest("POST", c.Url, strings.NewReader(string(jsonBody)))

Hope this helps!

答案3

得分: 0

我在Connor的答案中使用了NewRequest,但是使用struct然后进行编组对我来说似乎是一个不必要的步骤。

我直接将嵌套的JSON字符串传递给了strings.NewReader

import (
	"net/http"
	"strings"
)

reqBody := strings.NewReader(`{
    "method": {"server-method"},
    "arguments": {
        "download-dir": {"/path/to/downloads/dir"},
        "paused":       {"false"},
    },
}`)

req, err := http.NewRequest("POST", "https://httpbin.org/post", reqBody)

希望对那些被Go的http.PostForm困扰的人有所帮助,因为它只接受url.Values作为参数,而url.Values无法生成嵌套的JSON。

英文:

I used NewRequest as Connor mentions in his answer but using a struct and then marshalling it seems an unnecessary step to me.

I passed my nested json string straight to strings.NewReader:

import (
	"net/http"
	"strings"
)

reqBody := strings.NewReader(`{
    "method": {"server-method"},
    "arguments": {
        "download-dir": {"/path/to/downloads/dir"},
        "paused":       {"false"},
    },
}`)

req, err := http.NewRequest("POST", "https://httpbin.org/post", reqBody)

Hope it helps those who are stuck with Go's http PostForm which only accepts url.Values as argument while url.Values cannot generate nested json.

huangapple
  • 本文由 发表于 2016年11月7日 00:24:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/40451625.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定