在运行时覆盖 Go JSON 标签值



我在我的 Web 应用程序中使用 "encoding/json" 有以下结构

type CourseAssignment struct {
Semester int `json:"semester"  xml:"semester"`
Lecture Lecture `json:"-"  xml:"-"`
Cos Cos `json:"-"  xml:"-"`
Links map[string][]Link `json:"links,omitempty" xml:"links,omitempty"`
}

讲座和 Cos 本身就是复杂的结构,我不想包含在我的序列化 json 中,我通过设置 json 来指示:"-">

这非常有效。

如何在运行时按需重写该行为,而无需编写自己的序列化代码?

我自己的解决方案:

func (r *CourseAssignment) Expand(depth int) CourseAssignment {
if depth <= 0 {
return *r
}
tmp := *r
tmp.LectureEx = tmp.Lecture
tmp.CosEx = tmp.Cos
tmp.Links = nil 
return tmp
}
type CourseAssignment struct {
Semester int `json:"semester"  xml:"semester"`
Lecture *Lecture `json:"-"  xml:"-"`
Cos *Cos `json:"-"  xml:"-"`
Links map[string][]Link `json:"links,omitempty" xml:"links,omitempty"`
LectureEx  *Lecture   `json:"lecture,omitempty"  xml:"lecture,omitempty"`
CosEx *Cos `json:"course_of_study,omitempty" xml:"course_of_study,omitempty"`   
}

当我想包含字段时,我使用Expand创建对象的副本,该副本填充包含相同引用但显示在序列化中的字段。

您可以使用包中的StructTag读取/获取结构标记值reflect

package main
import (
"fmt"
"reflect"
)
type CourseAssignment struct {
Semester int `json:"semester"  xml:"semester"`
}
func main() {
ca := CourseAssignment{}
st := reflect.TypeOf(ca)
field := st.Field(0)
fmt.Println(field.Tag.Get("json"))
}

没有方法可以更改标准库中的结构标记字段。

但是,有一些开源库可以做到这一点,例如 Retag。

我在类似情况下所做的是将这些类型的字段设置为omitempty,然后在我不希望它们包含在 JSON 中的情况下在序列化之前清空它们:

type CourseAssignment struct {
Semester int `json:"semester"  xml:"semester"`
Lecture *Lecture `json:"lecture,omitempty"  xml:"-"`
Cos *Cos `json:"cos,omitempty"  xml:"-"`
Links map[string][]Link `json:"links,omitempty" xml:"links,omitempty"`
}
// Want to serialize without including Lecture/Cos:
aCourseAssignment.Lecture = nil
aCourseAssignment.Cos = nil
thing,err := json.Marshal(aCourseAssignment)

最新更新