为了账号安全,请及时绑定邮箱和手机立即绑定

在下联运期间处理不同类型的参数

在下联运期间处理不同类型的参数

Go
RISEBY 2022-08-01 10:40:55
我正在使用弗里茨的一些API!Box router,我想在一个体面的结构中取消json响应,只需要找到一个好方法来做到这一点。有时在API响应中,WLan参数是boool,有时是这种类型的对象。// WLan contains info about the Wireless Lantype WLan struct {    Txt     string `json:"txt"`    Led     string `json:"led"`    Title   string `json:"title"`    Link    string `json:"link"`    Tooltip string `json:"tooltip"`}如果需要有关代码的详细信息,可以使用 github 存储库。我需要添加布尔wlan参数,我试图复制“Data”结构并更改名称,但该解决方案对我来说听起来很糟糕。Wlan 包含在以下结构中:// Data contains data about the Fritz!Boxtype Data struct {    NasLink          string    `json:"naslink"`    FritzOS          FritzOS   `json:"fritzos"`    Webdav           int       `json:"webdav,string"`    Manual           string    `json:"MANUAL_URL"`    Language         string    `json:"language"`    AVM              string    `json:"AVM_URL"`    USBConnect       string    `json:"usbconnect"`    Foncalls         Foncalls  `json:"foncalls"`    VPN              VPN       `json:"vpn"`    Internet         Internet  `json:"internet"`    DSL              DSL       `json:"dsl"`    ServicePortalURL string    `json:"SERVICEPORTAL_URL"`    Comfort          Comfort   `json:"comfort"`    Changelog        Changelog `json:"changelog"`    TamCalls         TamCalls  `json:"tamcalls"`    Lan              External  `json:"lan"`    USB              External  `json:"usb"`    FonNum           External  `json:"fonnum"`    NewsURL          string    `json:"NEWSLETTER_URL"`    Net              Net       `json:"net"`    Dect             External  `json:"dect"`    WLan             WLan      `json:"wlan"`  //Wlan             bool      `json:"wlan"` # This is the other "case"}
查看完整描述

2 回答

?
慕莱坞森

TA贡献1810条经验 获得超4个赞

我不知道这是否是一个好的解决方案,我还是新手,但无论如何,你可以使用json。RawMessage并将财产的解封“延迟”到两个单独的结构字段之一。例如:wlan


package main


import (

    "encoding/json"

    "fmt"

)


// Data contains data about the Fritz!Box. (other fields omitted for brevity)

type Data struct {

    Language string           `json:"language"`

    NewsURL  string           `json:"NEWSLETTER_URL"`

    WLanRaw  *json.RawMessage `json:"wlan"`

    WLanBool bool             `json:"-"`

    WLanInfo *WLanInfo        `json:"-"`

}


// WLanInfo contains infos about the Wireless Lan

type WLanInfo struct {

    Txt     string `json:"txt"`

    Led     string `json:"led"`

    Title   string `json:"title"`

    Link    string `json:"link"`

    Tooltip string `json:"tooltip"`

}


func UnmarshalData(raw []byte, data *Data) error {

    if err := json.Unmarshal(raw, data); err != nil {

        return err

    }

    switch string(*data.WLanRaw) {

    case "true", "false":

        json.Unmarshal(*data.WLanRaw, &data.WLanBool)

    default:

        if err := json.Unmarshal(*data.WLanRaw, &data.WLanInfo); err != nil {

            return err

        }

    }

    return nil

}


func main() {

    jsonBool := []byte(`

{

    "language": "it",

    "NEWSLETTER_URL": "https://example.com/news",

    "wlan": true

}`)


    jsonInfo := []byte(`

{

    "language": "it",

    "NEWSLETTER_URL": "https://example.com/news",

    "wlan": {

        "txt": "footxt",

        "led": "fooled",

        "title": "hello",

        "link": "bar",

        "tooltip": "baz"

    }

}`)


    // error handling omitted

    var dataBool Data

    UnmarshalData(jsonBool, &dataBool)

    fmt.Printf("%+v\n\n", dataBool)


    var dataInfo Data

    UnmarshalData(jsonInfo, &dataInfo)

    fmt.Printf("%+v %+v\n", dataInfo, dataInfo.WLanInfo)

}

$ go build fritz.go

$ ./fritz

{Language:it NewsURL:https://example.com/news WLanRaw:0xc0000a4060 WLanBool:true WLanInfo:<nil>}


{Language:it NewsURL:https://example.com/news WLanRaw:0xc0000a4080 WLanBool:false WLanInfo:0xc0000b0000} &{Txt:footxt Led:fooled Title:hello Link:bar Tooltip:baz}

$


查看完整回答
反对 回复 2022-08-01
?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

你可以实现 json。Unmarshaler 和 json.封送线接口。


type WLan struct {

    Bool    *bool  `json:"-"`

    Txt     string `json:"txt"`

    Led     string `json:"led"`

    Title   string `json:"title"`

    Link    string `json:"link"`

    Tooltip string `json:"tooltip"`

}


// implements json.Unmarshaler

func (w *WLan) UnmarshalJSON(data []byte) error {

    if len(data) > 0 && (data[0] == 't' || data[0] == 'f') { // seems to be a bool

        w.Bool = new(bool)

        return json.Unmarshal(data, w.Bool)

    }

    if len(data) > 1 && data[0] == '{' && data[len(data)-1] == '}' { // it's an object

        // type W and the conversion (*W)(w) are required to

        // prevent encoding/json from invoking the UnmarshalJSON

        // method recursively causing a stack overflow

        type W WLan

        return json.Unmarshal(data, (*W)(w))

    }

    return nil // or error, up to you

}


// implements json.Marshaler

func (w WLan) MarshalJSON() ([]byte, error) {

    if w.Bool != nil {

        return json.Marshal(*w.Bool)

    }

    // Same as with UnmarshalJSON, type W and the conversion W(w) are 

    // required to prevent encoding/json from invoking the MarshalJSON

    // method recursively causing a stack overflow

    type W WLan

    return json.Marshal(W(w))

}

https://play.golang.org/p/s72zt4ny7Pv


查看完整回答
反对 回复 2022-08-01
  • 2 回答
  • 0 关注
  • 89 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信