在运行时覆盖Golang JSON标记值

时间:2017-07-11 10:53:37

标签: json go

我的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"`
}

Lecture和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"`   
}

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

2 个答案:

答案 0 :(得分:3)

您可以使用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

答案 1 :(得分:1)

我在类似情况下所做的是将这些类型的字段设置为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)