如果在Golang中解组时在json中找不到字段,是否可能生成错误?我在文档中找不到它。是否有任何标签指定所需的字段?
答案 0 :(得分:52)
encoding/json
包中没有标记将字段设置为“required”。您将需要编写自己的MarshalJSON()
方法,或对缺少的字段进行检查。
要检查缺少的字段,您必须使用指针来区分missing / null和zero值:
type JsonStruct struct {
String *string
Number *float64
}
完整的工作示例:
package main
import (
"fmt"
"encoding/json"
)
type JsonStruct struct {
String *string
Number *float64
}
var rawJson = []byte(`{
"string":"We do not provide a number"
}`)
func main() {
var s *JsonStruct
err := json.Unmarshal(rawJson, &s)
if err != nil {
panic(err)
}
if s.String == nil {
panic("String is missing or null!")
}
if s.Number == nil {
panic("Number is missing or null!")
}
fmt.Printf("String: %s Number: %f\n", *s.String, *s.Number)
}
答案 1 :(得分:5)
您还可以覆盖特定类型的解组(以便隐藏在几个json图层中的必填字段),而不必将该字段设为指针。
SELECT w.well_id,
w.WELL_NR,
w.WELL_NM,
w.WELL_API_NR,
ws.WELL_SGMNT_SIDE_TRCK_CD,
wc.WELL_CMPLTN_CD,
wc.WELL_SGMNT_ID,
wc.WELL_CMPLTN_ID
FROM WELL W
JOIN WELL_SGMNT ws
ON ws.well_id=w.well_id
JOIN WELL_CMPLTN wc
ON ws.WELL_SGMNT_ID=wc.WELL_SGMNT_ID
WHERE w.well_id ='13030' AND wc.WELL_CMPLTN_ID =
(SELECT MAX(wc.WELL_CMPLTN_ID)
FROM WELL W
JOIN WELL_SGMNT ws
ON ws.well_id=w.well_id
JOIN WELL_CMPLTN wc
ON ws.WELL_SGMNT_ID=wc.WELL_SGMNT_ID
WHERE w.well_id ='13030'
)
答案 2 :(得分:3)
您只需实现Unmarshaler接口即可自定义JSON的解组方式。
答案 3 :(得分:0)
这是检查自定义的tag
您可以像这样为您的结构创建标签:
type Profile struct {
Name string `yourprojectname:"required"`
Age int
}
使用reflect
检查代码是否分配了required
值
func (p *Profile) Unmarshal(data []byte) error {
err := json.Unmarshal(data, p)
if err != nil {
return err
}
fields := reflect.ValueOf(p).Elem()
for i := 0; i < fields.NumField(); i++ {
yourpojectTags := fields.Type().Field(i).Tag.Get("yourprojectname")
if strings.Contains(yourpojectTags, "required") && fields.Field(i).IsZero() {
return errors.New("required field is missing")
}
}
return nil
}
测试用例如下:
func main() {
profile1 := `{"Name":"foo", "Age":20}`
profile2 := `{"Name":"", "Age":21}`
var profile Profile
err := profile.Unmarshal([]byte(profile1))
if err != nil {
log.Printf("profile1 unmarshal error: %s\n", err.Error())
return
}
fmt.Printf("profile1 unmarshal: %v\n", profile)
err = profile.Unmarshal([]byte(profile2))
if err != nil {
log.Printf("profile2 unmarshal error: %s\n", err.Error())
return
}
fmt.Printf("profile2 unmarshal: %v\n", profile)
}
结果:
profile1 unmarshal: {foo 20}
2009/11/10 23:00:00 profile2 unmarshal error: required field is missing
您可以转到Playground查看完成的代码