【问题标题】:Omit struct field in JSON response在 JSON 响应中省略结构字段
【发布时间】:2020-12-12 23:17:18
【问题描述】:

我有一个结构体,其中一些字段如下:

type Test struct {
    ID        int          `json:"id"`
    Active    bool         `json:"active"`
    Object    []obj.Object `json:"objects"`
}

然后是一些将 Test 对象编码为 JSON 作为响应的处理函数,但在其中一个函数中,我想省略响应中的最后一个字段“对象”。我知道json:"-" 省略了它,但问题是我需要该字段用于其他功能。

我将对象编码为 JSON 的方式是使用这种方法:

 json.NewEncoder(w).Encode(t)

有什么方法可以实现吗?提前致谢!

【问题讨论】:

  • 如果你的结构真的只有两个你想编码的小对象,为什么不只用这两个创建一个新的(临时结构)?
  • 马克说什么,或play.golang.org/p/h6ijXT_44Dr
  • 重复。对此没有魔法编码/json 标志。使用 Marc 或 mkopriva 的解决方案。
  • @Marc 非常感谢!在调用 encode 时创建了 tmp 结构,并用来自对象 real strcut 的那些临时字段填充了这些临时字段。
  • @mkopriva 感谢您的回答!由于我没有太多字段,因此我选择在编码函数调用上传递临时结构,而不是按照您的建议进行定义。

标签: json api rest go mux


【解决方案1】:

您可以将 omitempty 标记与指针结构一起使用。在这种情况下,如果指针为 nil,则不会编组字段。(https://play.golang.org/p/7DihRGmW0jZ) 例如

package main

import (
    "encoding/json"
    "fmt"
)

type Test struct {
        ID          *int          `json:"id,omitempty"`
        Active      *bool         `json:"active,omitempty"`
        Object      *interface{}  `json:"objects,omitempty"`
}

func main() {
    var result Test
    id:= 1
    active := true

    result.ID = &id
    result.Active = &active
    
    b, err := json.Marshal(result)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%s\n", b)
}

【讨论】:

    【解决方案2】:

    @alessiosavi 使用omitempty 的解决方案通常是最简单的,但这里有一个替代解决方案,可用于更复杂的场景。这利用了这样一个事实,即只要 结构 相同,即使 标签 不同,值也可以转换为另一种类型:https://play.golang.org/p/ZT6gbhsXxmD

    type Test struct {
        ID     int      `json:"id"`
        Active bool     `json:"active"`
        Object []Object `json:"objects,omitempty"`
    }
    
    type Test2 struct {
        ID     int      `json:"id"`
        Active bool     `json:"active"`
        Object []Object `json:"-"`
    }
    
    func main() {
        var t Test
        t.ID = 1
        t.Active = true
        t.Object = make([]Object, 1)
        fmt.Println("Test:")
        json.NewEncoder(os.Stdout).Encode(t)
        fmt.Println("Test2:")
        t2 := Test2(t)
        json.NewEncoder(os.Stdout).Encode(&t2)
    }
    

    这在很多情况下都很有用,例如您不想在发送到 JSON 之前从字段中删除值,或者您有更复杂的数据结构。

    【讨论】:

      【解决方案3】:

      省略值的简单方法是使用omitempty标签作为json并编写一个返回对象的方法,如下所示:

      package main
      
      import (
          "encoding/json"
          "fmt"
          "os"
      )
      
      type Test struct {
          ID     int      `json:"id"`
          Active bool     `json:"active"`
          Object []Object `json:"objects,omitempty"`
      }
      
      type Object struct {
          TEMP string
      }
      
      func (t Test) getData() Test {
          return Test{ID: t.ID, Active: t.Active}
      }
      
      func main() {
          var t Test
          t.ID = 1
          t.Active = true
          t.Object = make([]Object, 1)
          fmt.Println(t)
          fmt.Println(t.getData())
          json.NewEncoder(os.Stdout).Encode(t)
          fmt.Println("--------")
          json.NewEncoder(os.Stdout).Encode(t.getData())
      }
      
      

      结果如下:

      {1 true [{}]}
      {1 true}
      {"id":1,"active":true,"objects":[{"TEMP":""}]}
      --------
      {"id":1,"active":true}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-18
        • 1970-01-01
        相关资源
        最近更新 更多