【问题标题】:How to check if there is null value in json.body in post request [duplicate]如何检查post请求中的json.body中是否有空值[重复]
【发布时间】:2019-12-29 15:24:25
【问题描述】:

我有一个包含 4 个字段的结构:

type Animal struct {
    Name string
    Age  int
    Zone int
}

我正在发送一个 json 对象以解码为结构的发布请求, json 应该如下所示:

{
"Age":10,
"Name":"Lion", 
"Zone":1,
}

我希望所有字段都是字段,但我不会填写所有字段并发送一些 json 之类的。

{
"Age":10,
"Zone":1,
}

json.Decoder 自动构建该 Filed 并将其设置为 ""(该类型的值为零)而不是 null。

如何设置 null 值或检查它是否为 null 并生成错误?

我希望结果是{Age:10, Zone:1, Name:null} 或者至少会产生一个错误!

这是我用来将 json 转换为 struct 的代码

animalModel := Animal{}
err := json.NewDecoder(r.Body).Decode(&animalModel)

【问题讨论】:

标签: json api go post


【解决方案1】:

你可以使用指针

type Animal struct {
    Name *string
    Age  int
    Zone int
}

或者一个包

import "github.com/guregu/null"

type Animal struct {
    Name null.String
    Age  int
    Zone int
}

【讨论】:

  • 当我使用指针并发送一个没有名称字段的 json 时,我收到一个恐慌说:运行时错误:无效的内存地址或 nil 指针取消引用
【解决方案2】:

string 不能为零。如果您想区分缺席字段null 值和空值"",您可以使用以下选项:

  1. 作为一种快速解决方案,您可以使用指针:
type Animal struct {
Name *string
}

缺点是你需要使用一个时间变量来设置这个字段。

  1. 更灵活的解决方案是为 Animal 结构实现 Unmarshaler 接口,并使用 temporal map[string]string 进行所需的检查并返回错误:
type Animal struct {
Name string
}

func (a *Animal) UnmarshalJSON(data []byte) error {
  m := map[string]interface{}{}
  err := json.Unmarshal(data, &m)
  if err != nil {
    return err
  }
  // check if field is exist
  name, exist := m["name"]
  if !exist {
    return fmt.Errorf("field 'name' should be present")
  }
  // check other fields...
  // ...

  // if all fields are ok, you can:
  // 1. set fields from map items
  a.Name = name
  ...

  // 2. call Unmarshal
  return json.Unmarshal(data, a)
}

这里的缺点是您需要“手动”检查每个字段。

  1. 下一步是使用重型机械:go-swaggergo-openapi。这些工具使您能够使用声明性模式 (OpenAPI) 对 JSON 数据执行检查,您可以轻松实现版本控制、发布 API 等等。 当然,对于 3 字段结构来说,它是过度设计的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 2019-09-09
    • 2010-11-25
    • 2014-05-16
    • 1970-01-01
    • 2019-11-18
    • 2011-05-13
    相关资源
    最近更新 更多