Golang表单编码嵌套结构

时间:2018-02-11 19:08:54

标签: go struct marshalling urlencode

我正在使用ajg/form包将我的嵌套结构封送到url编码数据。

package main
import (
    "fmt"
    "bytes"
    "github.com/ajg/form"
)
type Subject struct {
    SubjectTag      string `form:"tag,omitempty"`
    SubjectName    string `form:"name,omitempty"`
}
type Student struct {
    Name          string `form:"stud_name,omitempty"`
    SubjectList   []Subject `form:"subjects,omitempty"`
}
func main() {
    student := Student{
        Name: "newStudent",
        SubjectList: []Subject{
            {SubjectTag:  "mathstag", SubjectName: "maths"},
            {SubjectTag:  "englishtag", SubjectName: "english"},
        },
    }
    runParse(student)
}
func runParse(i interface{}) {
    buf := new(bytes.Buffer)
    form.NewEncoder(buf).Encode(i)
    body := buf.String()
    fmt.Printf("Body: %#v\n", body) 
    // Prints Body: "subjects.0.name=maths&subjects.0.tag=mathstag&subjects.1.name=english&subjects.1.tag=englishtag&stud_name=newStudent"
    //After this I create an HTTP request client, and send a POST request with this body to a server.
}

问题是我的服务器没有理解点分隔的POST主体,但是它确实理解了这种格式的主体 - "subjects[0][name]=maths&subjects[0][tag]=mathstag&subjects[1][name]=english&subjects[1][tag]=englishtag&stud_name=newStudent",我已经用Postman测试过了。如何使用上面的结构创建这样的主体?我还可以使用其他任何套餐吗?

1 个答案:

答案 0 :(得分:0)

ajg/form包不是为了轻松实现这一目标而设计的。包form.go中的form将常量defaultDelimiter定义为句点/点(.)符文。然后在同一个包中的encode.godecode.go中使用它,在Encoder结构中设置为字段值,然后在调用{{1}中的方法时作为参数传入}。

您可以使用不同的字符轻松覆盖默认分隔符,在此处指定为符文node.go

r

将分隔符从点更改为您指定为符文encoder := form.NewEncoder(buf) encoder.DelimitWith(r)

的任何内容

超越这一点需要重写几种方法,可能是通过创建嵌入其中的原始类型的中间类型,然后在需要时定义覆盖函数。例如,r中的第27行:

node.go

必须进行更改,因此它不仅仅会连接分隔符y.merge(d, e, p+escape(d, e, k)+string(d), vs) ,而是围绕括号(或引号或引号,或者您设置它使用的任何内容),因为它最好是这是可配置的。)

d添加对自定义分隔符和转义符的支持时,您可以通过查看此差异来了解代码的哪些区域需要更改:https://github.com/ajg/form/commit/66a87187c6cd884319abb7b97b623e9bb30e075b

如果您不想接受所有这些新类型和方法覆盖,您可以编写自己的代码将ajg包输出转换为您需要的格式,或者查看配置/更新服务器识别单字符分隔格式。

如果服务器端修复程序不容易获得,那么更好的方法是分叉/克隆ajg/form存储库,添加可选的左+右封闭分隔符支持,并在获得后提交拉取请求工作