我正在使用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测试过了。如何使用上面的结构创建这样的主体?我还可以使用其他任何套餐吗?
答案 0 :(得分:0)
ajg/form
包不是为了轻松实现这一目标而设计的。包form.go
中的form
将常量defaultDelimiter
定义为句点/点(.
)符文。然后在同一个包中的encode.go
和decode.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
存储库,添加可选的左+右封闭分隔符支持,并在获得后提交拉取请求工作